Production-oriented Go API skeleton for a Norwegian accounting backend (PostgreSQL, Chi, pgx, sqlc).
- Go 1.23+
- Docker (optional, for Compose and for
make sqlc-docker)
-
Copy
.env.exampleto.envif you want Compose or shell to pick up the same values (optional; the compose file sets the essentials for theapiservice). -
Start Postgres, the API, and the background worker:
docker compose up --build
Or:
make docker-up(same asdocker compose up --build). Theworkerservice runscmd/workeragainst the same database; scale it or leave it at one replica as needed.Next.js web + auth DB in the same Compose: if you also have the
saldrafrontend repo as a sibling directory, use itsdocker-compose.yml(build context../saldra-api) instead of this file’s stack to avoid two Postgres instances on the same ports. -
Probes:
- Liveness —
GET http://localhost:8080/health/live - Readiness (DB ping via sqlc) —
GET http://localhost:8080/health/ready
- Liveness —
With PostgreSQL reachable (for example Compose running only the postgres service, or a local install):
# Load variables from .env into your shell (optional)
set -a && source .env && set +a
make build
./bin/apiFaster iteration without writing bin/api:
set -a && source .env && set +a
make run-devFor readable logs in the terminal, set LOG_FORMAT=text in .env or your environment.
Configuration is read from environment variables; see .env.example for names and defaults. DATABASE_URL is required.
| Target | Description |
|---|---|
make tidy |
go mod tidy |
make fmt |
go fmt ./... |
make vet |
go vet ./... |
make test |
Run tests |
make build |
Build bin/api |
make worker |
Build bin/worker (background jobs) |
make run |
Build and run bin/api |
make run-dev |
go run ./cmd/api (no bin/ step) |
make sqlc |
Regenerate internal/store/db (local sqlc) |
make sqlc-docker |
Same, using the sqlc/sqlc image |
make docker-up / make docker-down |
Compose stack |
internal/app/bootstrap— Constructs the database pool, sqlc queries, HTTP router, andhttp.Server. Keepscmd/apiand signal/shutdown logic ininternal/appsmall as the system grows.- Logging —
log/slogwith JSON by default (LOG_FORMAT=json);textis intended for local development. - HTTP — Chi with client IP, panic recovery, request IDs, structured access logs, and a configurable per-request timeout.
- Shutdown — SIGINT/SIGTERM stop new work;
http.Server.ShutdownrespectsSHUTDOWN_TIMEOUT, then the pool closes.
Versioned JSON APIs under /v1 require authentication. Until OAuth/JWT is wired, send the demo principal id:
X-Principal-ID: 00000000-0000-0000-0000-000000000002 (see migration seed for demo@example.com and membership on the demo org).
See ARCHITECTURE.md for layering, tenants, and RBAC. For versioning, pagination, idempotency, and integration clients, see docs/API_GUIDELINES.md and openapi/openapi.yaml.