# ADR-001: chi over Echo **Status:** Accepted **Date:** 2026-03-18 ## Context httpserver needs an HTTP router. The two leading candidates were: - **chi** (`github.com/go-chi/chi/v5`) — a lightweight, idiomatic router whose root type implements `http.Handler` and whose middleware signature is `func(http.Handler) http.Handler` - **Echo** — a full web framework with its own `Context` type, its own middleware signature (`echo.MiddlewareFunc`), and handler signature (`echo.HandlerFunc`) The project constraint is that all transport-layer modules must compose cleanly with the rest of the micro-lib stack, which is built entirely on stdlib `net/http` types. `httpmw` middleware, `httputil` handler adapters, and all application handlers use `http.Handler` and `http.ResponseWriter`/`*http.Request` directly. ## Decision Use chi. Every chi middleware is `func(http.Handler) http.Handler`, every chi handler is `http.Handler`, and `chi.Router` itself satisfies `http.Handler`. This means: - Any middleware written for the stdlib works with chi without wrapping. - Any `http.Handler` can be registered directly without conversion. - `httputil.Handle` and `httputil.HandleNoBody` adapters slot in without adapter code. - The server itself can be tested with `httptest.NewRecorder` against the router directly, without starting a process. Echo would require wrapping every stdlib handler and middleware at the boundary, creating a permanent impedance mismatch between httpserver and the rest of the stack. ## Consequences - All route handlers and middleware in this project must use stdlib `net/http` types. No Echo-style context is available. - chi's URL parameter API (`chi.URLParam(r, "id")`) is used for path parameters rather than a framework-specific context method. - The chi dependency is a direct, visible import in `httpserver.go` and in any application that calls `srv.Route(...)` with a `func(chi.Router)` callback. This is accepted as the deliberate, explicit contract of the embedded router design (see ADR-002).