Golang / GoLang Production Patterns and Web Standards Interview Questions
What are the rules for writing HTTP responses correctly in Go handlers?
The http.ResponseWriter interface has ordering rules that are easy to violate, leading to subtle bugs where headers are silently lost or the response is malformed.
// http.ResponseWriter interface: // type ResponseWriter interface { // Header() http.Header // returns the header map (modify before WriteHeader) // WriteHeader(statusCode int) // sets status; can only be called once // Write([]byte) (int, error) // writes body; implicitly calls WriteHeader(200) // } // CORRECT ordering: func goodHandler(w http.ResponseWriter, r *http.Request) { // 1. Set headers first w.Header().Set("Content-Type", "application/json") w.Header().Set("X-Request-ID", "abc-123") // 2. Set status code w.WriteHeader(http.StatusCreated) // 201 // 3. Write body json.NewEncoder(w).Encode(map[string]string{"status": "created"}) } // WRONG: setting headers after WriteHeader Γ’ΒΒ silently ignored func badHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") // TOO LATE Γ’ΒΒ ignored! w.Write([]byte(`{"ok":true}`)) } // WRONG: calling Write before setting Content-Type // Write triggers an implicit WriteHeader(200) Γ’ΒΒ headers lock // Helper: structured JSON response func writeJSON(w http.ResponseWriter, status int, v any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(v); err != nil { log.Printf("writeJSON: %v", err) } } // IMPORTANT: returning from a handler does NOT automatically // stop a response from being written. Use explicit return after error: func handler(w http.ResponseWriter, r *http.Request) { if err := process(r); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return // MUST return Γ’ΒΒ otherwise code below also runs } writeJSON(w, http.StatusOK, map[string]string{"ok": "true"}) }
More Related questions...