I have the following HTTP handler function:
func (h *UptimeHttpHandler) CreateSchedule(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
dec := json.NewDecoder(r.Body)
var req ScheduleRequest
if err := dec.Decode(&req); err != nil {
// error handling omited
}
result, err := saveToDb(req)
if err != nil {
// error handling omited
}
// Responding with 201-Created instead of default 200-Ok
w.WriteHeader(http.StatusCreated)
enc := json.NewEncoder(w)
if err := enc.Encode(result); err != nil {
// this will have no effect as the status is already set before
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "%v", err)
}
}
Above code does the following:
- Request comes as a JSON data. It is decoded into
req
- Request is persisted in the DB. This returns a result object which will be the response
Now here, as soon as the DB insert is successful, we set the status code to 201
. Then use a JSON encoder to stream the JSON encoded value directly to ResponseWriter
.
When encode
returns an error, I need to change the status code to 500
. But currently I can't do it as Go allows to set the status code only once.
I can handle this by keeping the encoded JSON in memory, and setting the status code only when it is success. But then this creates unwanted copies and not really nice.
Is there a better way to handle this?