What does this handler send to the client, and why?
Question 450MediumGo 1.22 to 1.25
func h(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
}
The client gets status 200, Content-Type: text/plain; charset=utf-8, body hello. The server logs http: superfluous response.WriteHeader call.
Why: the first Write implicitly calls WriteHeader(200), and since no Content-Type was set, the server sniffs the first 512 bytes (http.DetectContentType). Headers are flushed at that point; later Header().Set modifies a map nobody reads, and the second WriteHeader is ignored.
Correct order: set headers → WriteHeader → Write.
func h(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]string{"status": "created"})
}
Related gotcha: http.Error after partially writing a body produces a garbled response; decide on errors before writing. Trailers must be declared in the Trailer header before writing, or use the http.TrailerPrefix.
More on Standard Library, HTTP & Systems Design in Go
- Q448Why must you close resp.Body, and why is closing alone sometimes not enough?
- Q449How is context used in net/http on both server and client sides? What happens when a client disconnects mid-request?
- Q451Explain encoding/json struct tag behavior: omitempty, omitzero, "-", and ",string". What does this print?
- Q452What does this print? How do you preserve large integer precision when decoding unknown JSON?
- Q453You implemented MarshalJSON but it isn't called. Why? Explain receiver rules and the recursion trap.
- Q454json.Unmarshal vs json.Decoder: when to use each, and how do you safely decode a request body?