Production-ready starter for HTTP APIs. It wires a clean architecture, sensible defaults, and an internal toolkit for routing, middleware, logging, DB access, migrations, validation, and docs.
# Start dev stack (API + DB) with live reload
make dev
# Apply migrations (inside docker)
cd api && make migrate-up
# Health check and docs
make health # GET http://localhost:8000/health
# Docs at http://localhost:8000/docs.
├── Makefile # top-level helpers that delegate to ./api
├── docker-compose.yml # dev stack (api, db, test runner)
├── README.md # this file
└── api/ # the actual API service
├── Makefile # API tasks (swag, test, lint, health, migrate)
├── Dockerfile # production image
├── Dockerfile.dev # dev image with hot-reload
├── go.mod, go.sum # module (replace to local toolkit wired)
├── api-toolkit/ # internal toolkit (router, db, logging, etc.)
│ ├── bootstrap/ # helpers for DB, router, server, migrations
│ ├── middleware/ # json, metrics, timeout, trace, rate-limit...
│ ├── httpx/, specs/ # error helpers, path constants (metrics, etc.)
│ └── ...
├── cmd/
│ ├── api/ # HTTP server entrypoint
│ │ └── main.go
│ └── migrate/ # CLI for DB migrations
│ └── main.go
├── internal/ # app-internal adapters (HTTP, middleware, ...)
│ └── http/
│ ├── handlers/ # thin HTTP handlers (mount under routes)
│ └── ...
├── migrations/ # SQL migrations (embedded) + go:embed binder
├── src/ # domain/application code
│ ├── repos/ # repositories (SQL via pgx)
│ ├── services/ # business services (e.g. foosvc)
│ └── specs/ # API endpoint paths and public types
├── swagger/ # generated OpenAPI docs
└── test/ # integration tests (run in container)
- Toolkit bootstrap
api/api-toolkit/bootstrap:OpenAndPingDB,NewDefaultRouter,MountSystemEndpoints,StartServer,NewMigrator.
- Entrypoints
api/cmd/api: loads config, opens DB, runs migrations on start (optional), wires services/handlers, starts HTTP server.api/cmd/migrate: CLI to runup,down,statususing the same embedded migrations as the server.
- Domain
api/src/services/foosvc: example service showing patterns for validation, transactions, IDs, and clock usage.api/src/repos: data access withpgxpools and context.
- HTTP
api/internal/http/handlers: decode → validate → service → encode.- Health at
/health, metrics at/metrics, docs at/docs.
api/.envlocal dev for API (not committed)api/.env.exampleexample of required vars for APIapi/.env.testlocal test env (not committed)api/.env.test.exampleexample for tests/.envdocker-compose env (not committed)
Rules:
- Load env at startup; fail fast if required variables are missing.
- Document new envs in the corresponding
.env.examplefiles. - Integration tests must use a separate
.env.test.
Top-level delegates into ./api:
make dev # docker compose up (hot reload)
make down # stop and clean volumes
make build # build images
make codegen # generate swagger and sync artifacts
make test # run tests (inside container)
make fmt # gofmt -s -w
make lint # go vet + golangci-lint
make health # show logs + curl health endpointAPI-specific (from api/):
make swag # regen swagger from cmd/api/main.go
make migrate-up # apply migrations
make migrate-down # rollback (dangerous; off in server)
make migrate-status # show applied/pending migrations- SQL lives in
api/migrations/*.up.sqland*.down.sqlwith timestamped names. - The API can run
upon start ifMIGRATE_ON_START=true. - Sources:
- Embedded (default): bundled via
go:embed(migrations_embed.go). - Directory: set
MIGRATIONS_DIR=/path/to/sqlto override.
- Embedded (default): bundled via
- Model your domain in
api/src/servicesandapi/src/repos. - Add HTTP handlers in
api/internal/http/handlersand mount underapi/src/specs/endpointspaths. - Add/modify migrations in
api/migrationsand runmake migrate-up. - Regenerate docs with
make codegen. - Run
make fmt,make lint,make test,make health.
- Replace
foosvcwith your service name and follow the same wiring incmd/api/main.go(repositories → services → handlers → routes). - Keep handlers thin and push logic into services.
- Always accept
context.Contextfor blocking or external operations. - Use the provided logger, validator, ID generator, and clock via dependency injection for testability.
- Health:
GET /health - Metrics:
GET /metrics(Prometheus) - Docs:
GET /docs - Version:
GET /version