Go
JSON API
Learn to write an HTTP endpoint returning JSON.
A JSON API
A JSON endpoint follows these steps: validate the request → decode the body → do the work → write a JSON response with a suitable status code. A small helper reduces repetition:
func jsonYaz(w http.ResponseWriter, kod int, v any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(kod)
json.NewEncoder(w).Encode(v)
}
If errors are returned as JSON too, the client deals with a single format: {"hata":"ad boş olamaz"}.
Validation and 201
An example create endpoint:
func ekle(w http.ResponseWriter, r *http.Request) {
var u Urun
r.Body = http.MaxBytesReader(w, r.Body, 1<<20)
if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
jsonYaz(w, 400, map[string]string{"hata": "geçersiz JSON"})
return
}
if u.Ad == "" {
jsonYaz(w, 422, map[string]string{"hata": "ad boş olamaz"})
return
}
jsonYaz(w, 201, u)
}
Exercise Create endpoint
Write the jsonYaz and ekle functions above (Urun contains only Ad string `json:"ad"`). Send two POST requests with the bodies {"ad":"Kalem"} and {"ad":""} and print both status codes on one line.
Show example solution
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
)
type Urun struct {
Ad string `json:"ad"`
}
func jsonYaz(w http.ResponseWriter, kod int, v any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(kod)
json.NewEncoder(w).Encode(v)
}
func ekle(w http.ResponseWriter, r *http.Request) {
var u Urun
r.Body = http.MaxBytesReader(w, r.Body, 1<<20)
if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
jsonYaz(w, 400, map[string]string{"hata": "geçersiz JSON"})
return
}
if u.Ad == "" {
jsonYaz(w, 422, map[string]string{"hata": "ad boş olamaz"})
return
}
jsonYaz(w, 201, u)
}
func main() {
kod := func(govde string) int {
rec := httptest.NewRecorder()
ekle(rec, httptest.NewRequest("POST", "/urunler", strings.NewReader(govde)))
return rec.Code
}
fmt.Println(kod(`{"ad":"Kalem"}`), kod(`{"ad":""}`))
}
Test yourself
-
Which limits the size of a request body?
- w.WriteHeader(413)
- json.Decoder.Limit
- http.MaxBytesReader(w, r.Body, n)
- r.ContentLength = n
Show answer
http.MaxBytesReader(w, r.Body, n) — MaxBytesReader cuts reading with an error after n bytes, preventing memory exhaustion with oversized bodies.
-
Content type
w.Header().Set("Content-Type", "____")
json.NewEncoder(w).Encode(v)
Show answer
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(v)
-
Situation and code
- Created
- 201
- Bozuk JSON
- 400
- Invalid field
- 422
- Body too large
- 413
Next lesson: Summary - net/http