Passing json to Rest handlers in Go.

In Go, you should know about exported fields. Exported fields must be capitalized. Also, there are two ways to parse json data. Marshaling and marshaling is one way, the other is decoding. Decoding deals with streams. Since we are dealing with the request to a Rest handler it is a stream. Therefore we should opt to use the NewDecode method found in the “encoding/json” package.

Here is the code.

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

// Make sure to capitalize exported fields. 
// indicate `json:"[field name]"` for decoding/encoding
type Person struct {
    Name    string `json:"name"`
    Profile []struct {
        Email   string `json:"email"`
        Address string `json:"address"`
        Job     string `json:"job"`
        Error   struct {
            Code string `json:"code"`
        } `json:"error"`
    } `json:"profile"`
}

func main() {
    // Route calls to /hello to the helloHandler
    http.HandleFunc("/hello", helloHandler)
    
    // Routing fails kill the app
    log.Fatal(http.ListenAndServe(":8081", nil))
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
    //initialize an empty instance of Person
    var u Person
    if r.Body == nil {
        http.Error(w, "Please send a request body", 400)
        return
    }
    // Always handle errors first
    err := json.NewDecoder(r.Body).Decode(&u)
    if err != nil {
        http.Error(w, err.Error(), 400)
        return
    }
    // We can see in the console what was sent in the Profile
    fmt.Println(u.Profile)
    // Return a part of the decoded request for validation
    fmt.Fprintf(w, "%s", u.Profile[0].Email)
}


To call this while debugging

GET /hello HTTP/1.1
Host: localhost:8081
Content-Type: text/plain

{
    "name":"Mr. Patrick",
    "profile": [
        {
            "email": "patrick@sample.com",
            "address": "44 Main St",
            "job": "code monkey",
            "error": {
                "code":"123ABC"
            }
        }
    ]
}