1 · Before you read — commit to an answer
payload := map[string]any{
"replicas": 3,
"namespace": "production",
"name": "web-1",
}
body, _ := json.Marshal(payload)
fmt.Println(string(body))
{"name":"web-1","namespace":"production","replicas":3}
Commit to the exact bytes — including the key order — before reading on.
That pretest hides a guarantee worth knowing: json.Marshal always emits map keys in sorted order, no matter how the literal was written. Insertion order is gone; alphabetical order is what hits the wire. That's what makes JSON output diffable in tests.
Decoding Response Bodies
2 · Worked example — read every step
// Option 1: json.NewDecoder (streaming, preferred for HTTP)
var pods []Pod
if err := json.NewDecoder(resp.Body).Decode(&pods); err != nil {
return fmt.Errorf("decoding response: %w", err)
}
// Option 2: read all, then unmarshal (when you need the raw bytes too)
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("reading body: %w", err)
}
var pods []Pod
if err := json.Unmarshal(body, &pods); err != nil {
return fmt.Errorf("parsing JSON: %w", err)
}
Building Request Bodies
// POST with JSON body
payload := map[string]any{
"name": "web-1",
"namespace": "production",
"replicas": 3,
}
body, err := json.Marshal(payload)
if err != nil {
return fmt.Errorf("encoding body: %w", err)
}
req, err := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
3 · Fill the gaps
The outbound half again, from memory — data to wire bytes, wrapped for the request, plus the header APIs check.
payload := map[string]any{"name": "web-1", "replicas": 3}
body, err := json.
if err != nil {
return fmt.Errorf("encoding body: %w", err)
}
req, err := http.NewRequest("POST", url, )
if err != nil {
return fmt.Errorf("creating request: %w", err)
}
req.Header.Set(, "application/json")
4 · From scratch — this feeds your review queue