Skip to content

@tank/go-api-patterns

1.0.0

Description

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-patterns

Go API Patterns

Core Philosophy

  1. 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.
  2. 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().
  3. 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.
  4. 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.
  5. 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?"

NeedRouter
Minimal API, Go 1.22+net/http ServeMux with method patterns
Route groups, middleware chain, chi ecosystemChi
Maximum performance, binding, validationGin
Balanced API, middleware, WebSocketEcho
Fiber/Express-like, fasthttp-basedFiber

-> 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?"

  1. Define an AppError type with status code + message + underlying error
  2. Write a handler adapter that returns error instead of writing directly
  3. Convert AppError to JSON response in the adapter -> See references/middleware-and-errors.md

"How do I test my API?"

  1. Use httptest.NewRecorder() for unit tests
  2. Use httptest.NewServer() for integration tests
  3. Table-driven tests with subtests for each endpoint -> See references/data-and-testing.md

Decision Trees

Router Selection

SignalChoice
Go 1.22+, simple CRUD, few routesnet/http ServeMux
Need route groups, param middlewareChi (net/http compatible)
High-throughput, JSON binding/validation built-inGin
WebSocket support, HTTP/2, clean APIEcho
Coming from Node/Express, want fasthttpFiber

Database Library

SignalChoice
Maximum control, raw SQL, connection pool tuningpgx (PostgreSQL)
Multiple databases, struct scanning, named paramssqlx
Code-generated type-safe queriessqlc
ORM with schema-as-code, graph traversalent
Simple key-value or document storedatabase/sql + driver

Error Strategy

SignalApproach
Simple API, few error typesSentinel errors + HTTP status mapping
Complex domain, rich errorsCustom AppError type with codes
Multi-service, error chainingWrapped errors with errors.Is/As

Reference Index

FileContents
references/project-layout.mdDirectory structure, cmd/internal separation, package design, dependency injection, and composition rules
references/routing-and-handlers.mdnet/http ServeMux (Go 1.22+), Chi, Gin, Echo, Fiber comparison, handler signatures, request decoding, response writing, route organization
references/middleware-and-errors.mdMiddleware chaining, logging, auth, recovery, CORS, timeouts, AppError design, panic recovery, consistent HTTP error responses
references/data-and-testing.mdpgx, sqlx, sqlc, ent, repository boundaries, transactions, connection pools, httptest, table-driven tests, integration tests, and testcontainers
references/operations-and-deployment.mdEnvironment config, slog, request IDs, graceful shutdown, health probes, Docker builds, runtime tuning, and observability basics

Command Palette

Search skills, docs, and navigate Tank