When I make a request to the server without passing and value in the body I get and error massage as: EOF.
But I get default values in these fields if I pass a body like { }
How does this behavior work ?
func (app *application) createMovieHandler(w http.ResponseWriter, r *http.Request) {
var input struct {
Title string `json:"title"`
Year int32 `json:"year"`
Runtime int32 `json:"runtime"`
Genres []string `json:"genres"`
}
fmt.Println(r.Body)
err := json.NewDecoder(r.Body).Decode(&input)
if err != nil {
app.errorResponse(w, r, http.StatusBadRequest, err.Error())
return
}
fmt.Fprintf(w, "%+v\n", input)
}
I expected to get Zero Values on both of the cases.
You get an EOF
error in both cases.
EOF
is returned immediately with an empty body because the decoder finds no JSON value to decode before reaching the reader's end. This call will not modify the destination variable since no JSON was found to decode into that value.
When you pass a body containing {}
, the decoder will decode that value successfully. However, since the JSON object contains no properties, decoding it will not affect the destination variable.
{}
is not equivalent to { "title": "" }
If you were to attempt to decode a further value using the same decoder, you would then get the EOF
since the end of the reader was reached as a result of decoding the previous value. Again, the destination variable is not affected.
The only scenario in which decoding JSON value will modify the existing fields in a destination variable is when the JSON being decoded contains properties that correspond to those fields.
I have created a go playground to illustrate the above:
func main() {
dest := struct {
Title string
}{
Title: "as initialised",
}
fmt.Println("decode empty: ", json.NewDecoder(bytes.NewReader([]byte{})).Decode(&dest))
fmt.Println("dest.Title: ", dest.Title)
zdecoder := json.NewDecoder(bytes.NewReader([]byte("{}")))
fmt.Println("decode zero (1st):", zdecoder.Decode(&dest))
fmt.Println("dest.Title: ", dest.Title)
fmt.Println("decode zero (2nd)", zdecoder.Decode(&dest))
fmt.Println("dest.Title: ", dest.Title)
fmt.Println("decode zerotitle: ", json.NewDecoder(bytes.NewReader([]byte(`{"title":""}`))).Decode(&dest))
fmt.Println("dest.Title: ", dest.Title)
}