JSON responses
Read request bodies and write JSON results and errors from a handler.
Most handlers read a JSON body and write a JSON response. The package gives you a small set of helpers for both sides so a handler stays short and consistent.
Reading a request body
ReadJSON decodes the request body into a value you supply. Map a decode failure to a 400 with WriteBadRequest, which sends the error as a JSON body.
func createItem(w http.ResponseWriter, r *http.Request) {
var in CreateItem
if err := server.ReadJSON(r, &in); err != nil {
server.WriteBadRequest(w, err)
return
}
// ... use in
server.WriteJSON(w, http.StatusCreated, Item{ID: "1"})
}When you need the body as bytes rather than a decoded struct, ReadRawJSON returns it as a json.RawMessage after checking it is well-formed JSON. This is useful when you forward the payload on or decode it later against a schema chosen at runtime.
Writing a response
WriteJSON sets the application/json content type, writes the status code, and encodes the value.
server.WriteJSON(w, http.StatusOK, Item{ID: "1", Name: "widget"})Writing an error
WriteError sends an error as a JSON ErrorResponse with the status code you choose. You map a domain error to its status yourself, which keeps the helper free of any assumption about your error model.
server.WriteError(w, http.StatusNotFound, errors.New("item not found"))The body is always shaped as {"error": "..."}. WriteBadRequest is the common case wrapped up, writing the error with a 400.
Note
Every response goes out as {"error": "..."} for failures and your own value for successes, so a client sees one predictable shape across the service.