Cody
Cody

Reputation: 1208

How to JSON-decode lowercased names into my struct?

I'm starting to go crazy trying to get Go to decode this json request body. Here's a sample request:

curl -X POST -d "{\"username\":\"foo\", \"password\":\"bar\"}" http://localhost:3000/users

And here's my handler:

mux.HandleFunc("/users", func(rw http.ResponseWriter, req *http.Request) {
        var body struct {
            username string
            password string
        }

        // buf := make([]byte, req.ContentLength)
        // req.Body.Read(buf)
        // fmt.Println(string(buf))
        //
        // The above commented out code will correctly print:
        // {"username":"foo", "password":"bar"}

        err := json.NewDecoder(req.Body).Decode(&body)
        if err != nil {
            rw.WriteHeader(http.StatusNotAcceptable)
            return
        }

        fmt.Printf("%+v\n", body)
        // prints -> {username: password:}
})

Like the comment suggests, I can verify that req.Body is indeed correct -- but for whatever reason, json.NewDecoder(req.Body).Decode(&body) never fills out the fields of body.

Any help would be greatly appreciated!

Upvotes: 1

Views: 775

Answers (1)

Not_a_Golfer
Not_a_Golfer

Reputation: 49235

The problem is that the json decoder does not deal with private struct fields. The fields in your body structs are private.

Rewrite it like so and it will work:

 var body struct {
        Username string `json:"username"` 
        Password string `json:"password"`
 }

basically the json:"username" is a way to tell the json decoder how to map the json name of the object to the struct name. In this instance, for decoding only, it is not necessary - the json decoder is smart enough to make the translation of the upper/lower case.

But if you use the object to encode json as well, you need it, or you'll have upper case field names in the resulting json.

You can use the json struct tags for a few more useful things, like omitting empty field from encoded json, or skipping fields entirely.

You can read more about the JSON struct tags in the documentation for json.Marshal: http://golang.org/pkg/encoding/json/#Marshal

Upvotes: 5

Related Questions