๐ŸŒHTTP BasicsLESSON

HTTP Basics

net/http: batteries included

Go's standard library ships with a production-capable HTTP package โ€” no framework required. net/http covers both the server and client sides. For the server, three concepts cover almost everything: the Handler interface, the ServeMux router, and ResponseWriter.

The Handler interface

Every HTTP handler in Go satisfies one interface:

ResponseWriter is where you write the response; *Request carries everything the client sent (URL, method, headers, body). Any type with a ServeHTTP method can be registered as a handler.

http.HandlerFunc

Writing a full type just to satisfy the Handler interface for a simple function is verbose. http.HandlerFunc is an adapter that promotes a plain function to a Handler:

In practice you usually just pass the function directly to mux.Handle or mux.HandleFunc.

http.NewServeMux โ€” routing

A ServeMux matches incoming request paths to registered handlers:

Go 1.22 added method-qualified patterns like "GET /users/{id}", but exact-path + manual method checking works everywhere.

Inspecting the request

*http.Request carries all the information sent by the client:

Writing responses

http.ResponseWriter is an interface with three key operations, and order matters:

  1. Set headers โ€” before calling WriteHeader
  2. Call WriteHeader with the status code (optional; defaults to 200 on first Write)
  3. Write the body

http.Error is a convenience shortcut that sets a plain-text body and status in one call:

Middleware pattern

Middleware wraps a handler to run code before and/or after the inner handler. It returns a new Handler, so middleware chains compose cleanly:

Because the return type is http.Handler, you can stack multiple middleware layers:

Testing with net/http/httptest

You never need to start a real server to test your handlers. The net/http/httptest package provides in-process test helpers:

ResponseRecorder stores the status code, headers, and body in memory so you can assert on them after the handler returns. This makes handler tests fast, isolated, and free of network I/O.

Starting a real server

For completeness โ€” the one-liner to bind and serve (you cannot run this in the Playground because it blocks and requires a network):

In production code you usually call http.Server{Addr: ":8080", Handler: mux}.ListenAndServe() for more control over timeouts.

Knowledge Check

What interface must a Go HTTP handler implement?

What is http.HandlerFunc?

What does httptest.NewRecorder() return?