GO Web Services: Difference between revisions
Line 124: | Line 124: | ||
... | ... | ||
</syntaxhighlight> | </syntaxhighlight> | ||
===Create Handler=== | ===Create Handler and Determine Mathod=== | ||
We can now provide a GET method within the handler. The handler determines which method by looking at the request. | We can now provide a GET method within the handler. The handler determines which method by looking at the request. | ||
<syntaxhighlight lang="go"> | <syntaxhighlight lang="go"> | ||
Line 130: | Line 130: | ||
... | ... | ||
switch r.Method { | switch r.Method { | ||
// GET | |||
// POST | |||
// etc | |||
} | |||
} | |||
</syntaxhighlight> | |||
===GET Method=== | |||
We use the Mnmarshal method to encode the json | |||
<syntaxhighlight lang="go"> | |||
case http.MethodGet: | case http.MethodGet: | ||
productsJSON, err := json.Marshal(productList) | |||
if err != nil { | |||
w.WriteHeader(http.StatusInternalServerError) | |||
return | |||
} | |||
w.Header().Set("Content-Type", "application/json") | |||
w.Write(productsJSON) | |||
</syntaxhighlight> | |||
===POST Method=== | |||
We use the Unmarshal method to decode the json | |||
<syntaxhighlight lang="go"> | |||
case http.MethodPost: | |||
// add a new product to the list | |||
var newProduct Product | |||
bodyBytes, err := ioutil.ReadAll(r.Body) | |||
if err != nil { | if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | |||
return | |||
} | } | ||
err = json.Unmarshal(bodyBytes, &newProduct) | |||
if err != nil { | if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | |||
return | |||
} | |||
if newProduct.ProductID != 0 { | |||
w.WriteHeader(http.StatusBadRequest) | |||
return | |||
} | } | ||
newProduct.ProductID = getNextID() | |||
productList = append(productList, newProduct) | |||
w.WriteHeader(http.StatusCreated) | |||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 05:05, 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 and Determine Mathod
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 {
// GET
// POST
// etc
}
}
GET Method
We use the Mnmarshal method to encode the json
case http.MethodGet:
productsJSON, err := json.Marshal(productList)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(productsJSON)
POST Method
We use the Unmarshal method to decode the json
case http.MethodPost:
// add a new product to the list
var newProduct Product
bodyBytes, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
err = json.Unmarshal(bodyBytes, &newProduct)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if newProduct.ProductID != 0 {
w.WriteHeader(http.StatusBadRequest)
return
}
newProduct.ProductID = getNextID()
productList = append(productList, newProduct)
w.WriteHeader(http.StatusCreated)