GO Web Services: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 63: Line 63:
</syntaxhighlight>
</syntaxhighlight>
=Handling JSON=
=Handling JSON=
==Marshal and Unmarshal==
Every GO type implements the empty interface so any struct can be marshaled into JSON.
Every GO type implements the empty interface so any struct can be marshaled into JSON.
<syntaxhighlight lang="go">
<syntaxhighlight lang="go">
Line 81: Line 82:
f := foo{}
f := foo{}
json.Unmarshal([]byte(`{"Message":"4Score","Age":56, "Name":"Abe"}`), &f)
json.Unmarshal([]byte(`{"Message":"4Score","Age":56, "Name":"Abe"}`), &f)
</syntaxhighlight>
==Outputting To Handler==
===Type===
Lets make a type to encode
<syntaxhighlight lang="go">
package product
// Product
type Product struct {
ProductID      int    `json:"productId"`
Manufacturer  string `json:"manufacturer"`
Sku            string `json:"sku"`
Upc            string `json:"upc"`
PricePerUnit  string `json:"pricePerUnit"`
QuantityOnHand int    `json:"quantityOnHand"`
ProductName    string `json:"productName"`
}
</syntaxhighlight>
===Make Some Demo Data===
Here is some demo data.
<syntaxhighlight lang="go">
[
  {
    "productId": 1,
    "manufacturer": "Johns-Jenkins",
    "sku": "p5z343vdS",
    "upc": "939581000000",
    "pricePerUnit": "497.45",
    "quantityOnHand": 9703,
    "productName": "sticky note"
  },
  {
    "productId": 2,
    "manufacturer": "Hessel, Schimmel and Feeney",
    "sku": "i7v300kmx",
    "upc": "740979000000",
    "pricePerUnit": "282.29",
    "quantityOnHand": 9217,
    "productName": "leg warmers"
  },
...
</syntaxhighlight>
===Create Handler===
We can now provide a GET method within the handler. The handler determines which method by looking at the request.
<syntaxhighlight lang="go">
func handleProduct(w http.ResponseWriter, r *http.Request) {
...
switch r.Method {
case http.MethodGet:
productList := getProductList()
j, err := json.Marshal(productList)
if err != nil {
log.Fatal(err)
}
_, err = w.Write(j)
if err != nil {
log.Fatal(err)
}
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 04:53, 26 August 2021

Handling Requests

These are the two main ways to handle requests

  • Handle a handler to handle requests matching a pattern
  • HandleFunc a function to handle requests matching a pattern

Handle

Here is the signature for Handle.

func Handle(pattern string, handler Handler)

Handler is an interface which has the signature

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

So here is how to use this approach. We create a type and implement the interface required.

// Creating a handler type
type fooHandler struct {
  Message string
}

// Implementing the function for the interface
func (f *fooHandler) ServeHTTP(w http.ResponseWrite, r *http.Request) {
  w.Write( []byte(f.Message) )
}


func main() {
  http.Handle("/foo", &fooHandler{Message: "hello Word"})
}

Remember Remember we can construct a struct using a struct literal e.g.

type Student struct {
    Name string
    Age  int
}

pb := &Student{ // pb == &Student{"Bob", 8}
    Name: "Bob",
    Age:  8,
}

Requests

These consist of three parts

  • Method
  • Headers
  • Body

HandleFunc

Perhaps somewhat simpler. We just need to create a function with the correct signature

func main() {
  foo := funct(w http.ResponseWritter, _ *http.Response) {
    w.Write( []byte("hello world") )
  }

  http.HandleFunc("/foo", foo)
}

Handling JSON

Marshal and Unmarshal

Every GO type implements the empty interface so any struct can be marshaled into JSON.

func Marshal(v interface{}) (byte[]. error)

To ensure the struct is marshaled, all the fields need to be exported. In this example surname would not be marchaled.

type foo struct{
  Message string
  Age int
  surname string
}

json,Marshal(&foo{"4Score",56, "Lincoln"})

To Unmarshal

f := foo{}
json.Unmarshal([]byte(`{"Message":"4Score","Age":56, "Name":"Abe"}`), &f)

Outputting To Handler

Type

Lets make a type to encode

package product

// Product
type Product struct {
	ProductID      int    `json:"productId"`
	Manufacturer   string `json:"manufacturer"`
	Sku            string `json:"sku"`
	Upc            string `json:"upc"`
	PricePerUnit   string `json:"pricePerUnit"`
	QuantityOnHand int    `json:"quantityOnHand"`
	ProductName    string `json:"productName"`
}

Make Some Demo Data

Here is some demo data.

[
  {
    "productId": 1,
    "manufacturer": "Johns-Jenkins",
    "sku": "p5z343vdS",
    "upc": "939581000000",
    "pricePerUnit": "497.45",
    "quantityOnHand": 9703,
    "productName": "sticky note"
  },
  {
    "productId": 2,
    "manufacturer": "Hessel, Schimmel and Feeney",
    "sku": "i7v300kmx",
    "upc": "740979000000",
    "pricePerUnit": "282.29",
    "quantityOnHand": 9217,
    "productName": "leg warmers"
  },
...

Create Handler

We can now provide a GET method within the handler. The handler determines which method by looking at the request.

func handleProduct(w http.ResponseWriter, r *http.Request) {
...
	switch r.Method {
	case http.MethodGet:

		productList := getProductList()
		j, err := json.Marshal(productList)
		if err != nil {
			log.Fatal(err)
		}
		_, err = w.Write(j)
		if err != nil {
			log.Fatal(err)
		}

}