@tank/go-api-patterns
1.0.0Description
Production Go HTTP API development. Covers net/http ServeMux (Go 1.22+), Chi/Gin/Echo/Fiber routers, middleware patterns, context propagation, slog structured logging, error handling, database access (pgx, sqlx, ent), configuration, graceful shutdown, project layout, httptest testing, and Docker deployment.
Triggered by
go apigo rest apigo http servergo backendgo middlewarego chi
Download
Verified
tank install @tank/go-api-patternsGo API Patterns
Core Philosophy
- Standard library first — net/http is production-grade. Reach for a framework only when it saves significant boilerplate (route groups, parameter binding). A thin router like Chi adds value; a full framework adds coupling.
- Explicit over magic — Pass dependencies as constructor arguments, not globals. Use context.Context for request-scoped values, not package-level state. Wire things visibly in main().
- Errors are values — Return errors, wrap them with %w for context, handle them at the boundary. Panics are for programmer bugs, not business logic. Middleware recovers from panics; handlers return errors.
- Composition over inheritance — Build middleware as func(http.Handler) http.Handler. Stack behaviors by chaining, not by inheriting from a base controller. The http.Handler interface is the universal contract.
- Fail fast at startup, gracefully at runtime — Validate configuration, ping databases, and bind ports at startup. At runtime, drain connections on SIGTERM, respect context cancellation, and shut down cleanly.
Quick-Start: Common Problems
"How do I structure a Go API project?"
cmd/api/main.go # Wiring, server startup, graceful shutdown
internal/handler/ # HTTP handlers (transport layer)
internal/service/ # Business logic
internal/repository/ # Database access
internal/middleware/ # Custom middleware
internal/config/ # Configuration loading
Keep all Go packages in internal/ to prevent external imports.
-> See references/project-layout.md
"Which router should I use?"
| Need | Router |
|---|---|
| Minimal API, Go 1.22+ | net/http ServeMux with method patterns |
| Route groups, middleware chain, chi ecosystem | Chi |
| Maximum performance, binding, validation | Gin |
| Balanced API, middleware, WebSocket | Echo |
| Fiber/Express-like, fasthttp-based | Fiber |
-> See references/routing-and-handlers.md
"How do I write middleware?"
func Logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
slog.Info("request", "method", r.Method, "path", r.URL.Path, "dur", time.Since(start))
})
}
-> See references/middleware-and-errors.md
"How do I handle errors consistently?"
- Define an AppError type with status code + message + underlying error
- Write a handler adapter that returns error instead of writing directly
- Convert AppError to JSON response in the adapter
-> See
references/middleware-and-errors.md
"How do I test my API?"
- Use httptest.NewRecorder() for unit tests
- Use httptest.NewServer() for integration tests
- Table-driven tests with subtests for each endpoint
-> See
references/data-and-testing.md
Decision Trees
Router Selection
| Signal | Choice |
|---|---|
| Go 1.22+, simple CRUD, few routes | net/http ServeMux |
| Need route groups, param middleware | Chi (net/http compatible) |
| High-throughput, JSON binding/validation built-in | Gin |
| WebSocket support, HTTP/2, clean API | Echo |
| Coming from Node/Express, want fasthttp | Fiber |
Database Library
| Signal | Choice |
|---|---|
| Maximum control, raw SQL, connection pool tuning | pgx (PostgreSQL) |
| Multiple databases, struct scanning, named params | sqlx |
| Code-generated type-safe queries | sqlc |
| ORM with schema-as-code, graph traversal | ent |
| Simple key-value or document store | database/sql + driver |
Error Strategy
| Signal | Approach |
|---|---|
| Simple API, few error types | Sentinel errors + HTTP status mapping |
| Complex domain, rich errors | Custom AppError type with codes |
| Multi-service, error chaining | Wrapped errors with errors.Is/As |
Reference Index
| File | Contents |
|---|---|
references/project-layout.md | Directory structure, cmd/internal separation, package design, dependency injection, and composition rules |
references/routing-and-handlers.md | net/http ServeMux (Go 1.22+), Chi, Gin, Echo, Fiber comparison, handler signatures, request decoding, response writing, route organization |
references/middleware-and-errors.md | Middleware chaining, logging, auth, recovery, CORS, timeouts, AppError design, panic recovery, consistent HTTP error responses |
references/data-and-testing.md | pgx, sqlx, sqlc, ent, repository boundaries, transactions, connection pools, httptest, table-driven tests, integration tests, and testcontainers |
references/operations-and-deployment.md | Environment config, slog, request IDs, graceful shutdown, health probes, Docker builds, runtime tuning, and observability basics |