An HTTP event handler receives a request and writes the corresponding response. In Go, a handler works with an http.ResponseWriter for output and an *http.Request for input. A minimal health handler can write "OK"; writing the body implicitly produces HTTP 200 unless WriteHeader set another status first. section 8.3.1
The http.Handler interface lets a server invoke request-processing behavior through ServeHTTP. http.HandlerFunc adapts an ordinary function with the handler signature into that interface, so ListenAndServe can call the function for every incoming request. section 8.3.2
Listing 8.10 Shorten handler (link/rest/shortener.go)
package rest
import (
"fmt"
"log/slog"
"net/http"
"github.com/inancgumus/gobyexample/link"
)
// Shorten returns an [http.Handler] that shortens URLs.
func Shorten(
lg *slog.Logger, links *link.Shortener, #1
) http.Handler { #2
return http.HandlerFunc(func( #3
w http.ResponseWriter, r *http.Request, #3
) { #3
key, err := links.Shorten(r.Context(), link.Link{
Key: link.Key( #4
r.PostFormValue("key"), #4
), #4
URL: r.PostFormValue("url"), #4
})
if err != nil {
httpError(w, r, lg, fmt.Errorf( #5
"shortening: %w", err, #5
)) #5
return #6
}
w.WriteHeader(http.StatusCreated) #7
fmt.Fprint(w, key) #7
})
}
A handler factory can take explicit dependencies and return a closure. The returned handler reads POST form values, calls a Shortener, stops immediately after an error response, or writes 201 Created and the generated key. section 8.4.1
Build handlers around a few practical rules:
- Take dependencies as parameters rather than globals, making required collaborators visible and replaceable during tests. section 8.4.1
- After writing an error response, return immediately to prevent duplicate operations, inconsistent responses, or unintended side effects. section 8.4.1
- Register handlers on a ServeMux by route and method; the server sends incoming requests through the mux before a matching handler receives them. section 8.5.2
- Test a handler directly with httptest.NewRequest and httptest.NewRecorder, then assert the captured status code and response body. section 8.7.2 section 8.8.2
Health endpoint
A health endpoint can be a plain function: func Health(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "OK") }. Register it with mux.HandleFunc("/health", rest.Health), or convert it explicitly with http.HandlerFunc(Health) when an http.Handler is required. Its simple 200/OK response lets load balancers and orchestrators monitor availability. section 8.3.1 section 8.3.2 section 8.5.2
Handlers remain easy to test when production and test code share the same HTTP types. httptest supplies requests, response recorders, and isolated servers that work with http.Request, http.ResponseWriter, http.Server, and http.Handler rather than test-only mocks. section 8.8.2





















