Production-ready starter for HTTP APIs. It wires a clean architecture,
sensible defaults, and a shared toolkit module (github.com/aatuh/api-toolkit)
for routing, middleware, logging, DB access, migrations, validation, and docs.
Find and replace string api-boilerplate with your service name:
api-boilerplate(?!-core)Find each .env.example file and create .env files.
# Start dev stack (API + web + DB) with live reload
make dev
# Apply migrations (inside docker)
cd api && make migrate-up
# Build local binary with stamped version info
cd api && make build-bin
# Health check and docs
make health # GET http://localhost:8000/health
# Docs at http://localhost:8000/docs
# Web at http://localhost:3000I'm working on api-boilerplate project. Please refer to AGENTS.md backlog.md files in it. use /api-toolkit and /api-svc as reusable libraries. Always create best industry standard, hexagonal architecture, SOLID principles, clear, testable and developer friendly code. Your task: write task here.
.
├── 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 (depends on github.com/aatuh/api-toolkit)
│ ├── cmd/
│ │ ├── api/ # HTTP server entrypoint
│ │ │ └── main.go
│ │ └── migrate/ # CLI for DB migrations
│ │ └── main.go
│ ├── internal/ # app internals (services, stores, http)
│ │ ├── services/ # domain services (e.g. foosvc)
│ │ ├── store/ # repositories (SQL via pgx)
│ │ ├── validation/ # request validation helpers
│ │ └── http/
│ │ ├── handlers/ # thin HTTP handlers (mount under routes)
│ │ ├── mapper/ # DTO <-> domain mapping
│ │ └── ...
│ ├── migrations/ # SQL migrations (embedded) + go:embed binder
│ ├── src/
│ │ └── specs/ # API endpoint paths and public types
│ ├── swagger/ # generated OpenAPI docs
│ └── test/ # integration tests (run in container)
└── web/ # Next.js app + shared packages
├── src/ # app router pages and UI
├── content/ # markdown content pages
└── packages/
└── services/foo/ # demo domain, adapters, hooks, config
The web app consumes @api-boilerplate/* from the api-boilerplate-core repo
via git dependencies.
- Toolkit bootstrap
github.com/aatuh/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/internal/services/foosvc: example service showing patterns for validation, transactions, IDs, and clock usage.api/internal/store: data access withpgxpools and context.
- HTTP
api/internal/http/handlers: decode → validate → service → encode.- Health at
/health, metrics at/metrics, docs at/docs.
This repo depends on the released module version of github.com/aatuh/api-toolkit. For local cross-repo development, prefer a Go workspace instead of committing replace directives.
From a parent directory that contains both repos:
go work init ./api-boilerplate/api
go work use ./api-toolkitFrom the api-boilerplate/ repo root:
go work init ./api
go work use ../api-toolkitTo verify you’re using the published dependency versions (CI-like), run with GOWORK=off.
Docker Compose can also opt into the local toolkit checkout:
make dev TOOLKIT=1 # defaults to ../api-toolkit
# Optional: override toolkit checkout path
make dev TOOLKIT=1 API_TOOLKIT_PATH=$HOME/src/api-toolkit
# Equivalent docker compose invocation:
API_TOOLKIT_PATH=$HOME/src/api-toolkit docker compose -f docker-compose.yml -f docker-compose.toolkit.yml up -dapi/.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 codegen # 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
make build-bin # go build with version metadata (bin/api)To embed version info in the binary, run cd api && make build-bin. The
target stamps the git describe, commit SHA, and UTC build time via -ldflags
before producing bin/api. You can override these values:
cd api
VERSION=1.2.3 COMMIT=$(git rev-parse HEAD) DATE=$(date -u +%FT%TZ) make build-binThe version endpoint in cmd/api picks up the injected values automatically.
- 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/internal/servicesandapi/internal/store. - 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