go 47 lines · 8 steps

Safely decoding JSON in a Go HTTP handler

An HTTP handler that bounds request size, strictly decodes JSON, validates input, and maps each failure to the right status code.

Explained by highlit
1package api
2 
3import (
4 "encoding/json"
5 "errors"
6 "net/http"
7)
8 
9const maxCommentBody = 64 << 10
10 
11type createCommentRequest struct {
12 PostID int64 `json:"post_id"`
13 Body string `json:"body"`
14}
15 
16func (s *Server) handleCreateComment(w http.ResponseWriter, r *http.Request) {
17 r.Body = http.MaxBytesReader(w, r.Body, maxCommentBody)
18 
19 dec := json.NewDecoder(r.Body)
20 dec.DisallowUnknownFields()
21 
22 var req createCommentRequest
23 if err := dec.Decode(&req); err != nil {
24 var maxErr *http.MaxBytesError
25 if errors.As(err, &maxErr) {
26 http.Error(w, "request body too large", http.StatusRequestEntityTooLarge)
27 return
28 }
29 http.Error(w, "invalid request body", http.StatusBadRequest)
30 return
31 }
32 
33 if req.PostID == 0 || req.Body == "" {
34 http.Error(w, "post_id and body are required", http.StatusUnprocessableEntity)
35 return
36 }
37 
38 comment, err := s.comments.Create(r.Context(), req.PostID, req.Body)
39 if err != nil {
40 http.Error(w, "could not create comment", http.StatusInternalServerError)
41 return
42 }
43 
44 w.Header().Set("Content-Type", "application/json")
45 w.WriteHeader(http.StatusCreated)
46 json.NewEncoder(w).Encode(comment)
47}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Capping the request body with MaxBytesReader protects the server from clients that stream unbounded payloads.
  2. 2Distinguishing error types with errors.As lets one decode failure produce several precise HTTP responses.
  3. 3Validating required fields after decoding separates malformed JSON from semantically incomplete requests.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Safely decoding JSON in a Go HTTP handler — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code