Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
HTTP is five things: a method (GET, POST, PUT, DELETE, PATCH), a path (/users/42), a version (HTTP/1.1 or HTTP/2), a headers block, and a body. Status codes group into five bands: 1xx informational, 2xx success, 3xx redirect, 4xx client error, 5xx server error. You won't remember every code, but you'll use 200, 201, 204, 301, 302, 400, 401, 403, 404, 409, 422, and 500 constantly. curl -v shows you all of it.
HTTP's five-group status code system encodes every outcome a server can communicate: 2xx succeeded, 4xx the client did something wrong, 5xx the server did. A GET retrieves, a POST creates or triggers — and curl -v shows you the raw status line, headers, and body the same way every HTTP client in the world sees them. Reading that output fluently is the single fastest debugging skill you can build.
curl -v http://localhost:8080/users/42. Read every line of output.curl -v http://localhost:8080/users/99. Note the < HTTP/1.1 404 Not Found line. That's the status code.curl -v -X POST http://localhost:8080/users -d '{"name":"Ada"}' -H 'content-type: application/json'. Note the < HTTP/1.1 201 Created.-H 'Accept: application/xml' on the GET. Servers can handle content negotiation, but most won't. What does yours do?package main
import (
"encoding/json"
"io"
"net/http"
)
func main() {
mux := http.NewServeMux()
// GET /users/42 -> 200 with user
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
if id != "42" {
http.Error(w, "user not found", http.StatusNotFound) // 404
return
}
json.NewEncoder(w).Encode(map[string]string{"id": id, "name": "Ada"})
})
// POST /users -> 201 created
mux.HandleFunc("POST /users", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
w.WriteHeader(http.StatusCreated) // 201
w.Write(body)
})
http.ListenAndServe(":8080", mux)
}go run main.go