An OpenAPI-first Go service template with safe runtime defaults, optional PostgreSQL and agent-workflow profiles, observability, and CI.
Use this template · Quickstart · Documentation
This repository is a starting point for a Go HTTP API or microservice. It already connects the pieces most services need: an OpenAPI contract, configuration, health checks, graceful shutdown, telemetry, tests, Docker, CI, and repository instructions for coding agents.
The initialized service is small by default. It has no database, broker, or external provider dependency. You select the capabilities the service owns, and the initializer removes everything else instead of leaving dormant code behind.
- Start with a runnable service and spend the first commit on domain behavior.
- Keep the API contract, generated bindings, runtime wiring, and checks in one repository.
- Add PostgreSQL, jobs, messaging, gRPC, authentication, webhooks, or object storage through supported profiles when the service needs them.
- Give people and coding agents the same ownership rules and validation paths.
Create a repository from the template, initialize its identity, and run it:
gh repo create my-service \
--template Dankosik/go-service-template-rest \
--public \
--clone
cd my-service
make template-init \
MODULE=github.com/your-org/my-service \
CODEOWNER=@your-org/backend
ALLOW_FULL=1 make check
make runThis creates the minimal profile. make template-init rewrites the module,
service name, and CODEOWNERS; removes unused profiles; regenerates derived
code; and records the selection in template.lock.
| Area | Included |
|---|---|
| HTTP API | OpenAPI 3.0 as the client contract, with generated request bindings and typed responses |
| Runtime | chi, layered configuration, health and readiness, graceful shutdown with limits |
| Observability | OpenTelemetry traces and metrics, Prometheus export, structured logs |
| Validation | Focused Go tests, generated-code checks, race and goroutine leak coverage, CI matched to the change |
| Delivery | Dockerfile and GitHub Actions, with optional signed GHCR publication |
| Agent workflow | Shared repository rules and focused instructions, plus the selected tool adapter |
go.mod owns runtime and test dependencies. tools/go.mod
owns the portable development-tool set shared by every derived service.
Pass profile options to make template-init. Unset options use the minimal
none or core default.
| Need | Option | Adds |
|---|---|---|
| PostgreSQL | DATABASE=postgres |
pgx, Goose migrations, sqlc, and database lifecycle |
| Idempotent HTTP effects | DATABASE=postgres HTTP_IDEMPOTENCY=postgres |
The request effect and idempotency record in one transaction (guide) |
| Background jobs | DATABASE=postgres JOBS=postgres |
Typed River jobs and a separate worker (guide) |
| Outbound webhooks | DATABASE=postgres JOBS=postgres WEBHOOKS=durable |
Delivery jobs staged in the business transaction (guide) |
| Inbound webhooks | DATABASE=postgres JOBS=postgres INBOUND_WEBHOOKS=standard-webhooks |
Durable Standard Webhooks receipt and processing (guide) |
| NATS events | MESSAGING=nats-jetstream |
Typed publishing and a separate durable consumer worker (guide) |
| Transactional outbox | DATABASE=postgres OUTBOX=postgres MESSAGING=nats-jetstream |
Transactional event recording and a separate relay (guide) |
| Native gRPC | GRPC=enabled |
Generated clients and servers, health checks, streaming, and bounded drain (guide) |
| Authentication | AUTHN=oidc-jwt or AUTHN=oidc-introspection |
HTTP and gRPC bearer-token verification (guide) |
| Bounded outbound HTTP | OUTBOUND_HTTP=bounded |
An HTTP client locked to one upstream, with response-size limits |
| Machine authentication | OUTBOUND_AUTH=oauth2-client-credentials |
OAuth 2.0 client-credentials adapters (guide) |
| Object storage | OBJECT_STORAGE=s3 |
An S3-compatible client locked to one configured endpoint (guide) |
| Worked example | REFERENCE_EXAMPLE=keep |
A complete feature slice under examples/reference-service |
Profiles add code and validation, not infrastructure. Deployment still owns databases, streams, buckets, endpoints, and credentials. The initializer rejects unsupported profile combinations before it changes the repository.
flowchart LR
A["Create from template"] --> B["Keep required profiles"]
B --> C["Define the OpenAPI contract"]
C --> D["Add domain behavior"]
D --> E["Run focused checks"]
E --> F["CI and release"]
make template-initturns the template into one service and removes unused code.api/openapi/service.yamlowns the HTTP contract. Generated code carries requests and responses into handwritten handlers.internal/<feature>owns business behavior. Transport, database, and provider details stay underinternal/infra.- Package tests give fast feedback.
make proveis optional package-sized iteration;make verifyis the surface-aware final local route;ALLOW_FULL=1 make checkvalidates the whole repository before delivery. - CI selects its checks from the changed files. Image publication is opt-in and happens only after the matching checks pass.
Start the first real vertical slice with the first production feature guide.
AGENTS.md gives every supported agent the repository rules. .agents/skills
contains focused instructions for API contracts, architecture, data, security,
reliability, testing, delivery, and Go maintenance. Small local edits stay
direct. Bigger changes can record decisions under specs/ so another session
can continue without guessing.
Before handwritten Go edits, agents load version-specific guidance from
JetBrains Modern Go Guidelines,
pinned in tools/go.mod; focused and pull-request lint enforce modernize.
AGENT_HARNESS=core keeps the shared contract without a generated adapter.
Pass codex, claude, cursor, qwen, grok, opencode, or all to keep
the matching adapter. See Agent Harness and the
Spec-First Workflow for the complete routing
rules.
api/openapi/service.yaml HTTP API source of truth
cmd/service/ service entrypoint and runtime assembly
internal/<feature>/ business behavior
internal/infra/ HTTP, database, messaging, and provider adapters
internal/config/ runtime configuration
migrations/ PostgreSQL migrations when selected
test/ cross-package and process integration tests
docs/ architecture, operations, and development guides
.agents/skills/ reusable methods for coding agents
make/template.mk portable standard Make commands
make/service.mk optional service-owned Make extensions
scripts/init-module.sh profile selection and repository initialization
Use the placement guide
before adding a package. After initialization, make integration-init
scaffolds one outbound HTTP or gRPC integration from a committed local
contract; see the integration initializer.
| Command | Use it for |
|---|---|
make run |
Start the HTTP service locally |
make prove PKG=./pkg FILES='...' |
Optional package-sized format, test, and lint |
make verify |
Run the minimal integrated surface plan |
ALLOW_FULL=1 make check |
Run the full-repository aggregate once before delivery |
make test-integration |
Run the container-backed integration tests |
Use the narrowest check that can catch a problem in the change. The full command catalog and routing rules live in Build, test, and development commands and Validation routing.
Performance work uses make benchmark-capture, benchmark-compare, or
benchmark-http with an accepted workload, budget, and response owner. See
Benchmarking.
- Build the first feature: First production feature
- Understand ownership: Repository architecture
- Choose packages: Project structure and module organization
- Work with agents: Agent harness and Spec-first workflow
- Understand CI and releases: CI/CD production readiness
- Measure performance: Benchmarking
- Deploy on Railway: Railway deployment profile
Contributions are welcome. Read CONTRIBUTING.md, use the issue forms for bugs and feature proposals, and follow the Code of Conduct.
Report vulnerabilities privately through SECURITY.md.
Released under the MIT License.
