Template Service
The reference Go service — copy this directory to start a new service.
The template service is a real, compiled, tested service. Its domains (domain1, domain2) are
throwaway samples, but the wiring is what you copy: Postgres, idempotent Command: An HTTP POST that changes state, recorded with an Idempotency-Key so retries do not double-apply; not CQRS or a command bus.
handling via command.Execute, per-domain Transactional outbox: Each domain inserts events into its own <domain>_events table in the same transaction as the state change; a publisher drains unpublished rows to Azure Service Bus. tables, and a
Response envelope: The template service wraps every JSON response in {header, payload}. A success payload is {data} (a record or a list) plus optional meta.pagination; accounting still returns bare bodies and RFC 9457 errors until the divergence is resolved. on every JSON response.
- Domain
- Services
- Kind
- Go HTTP service
- Lifecycle
- Active
- flowctl project
- None
- Stacks
- Runs on its own
- Source
- services/template
Run it locally
make dev-template, Swagger UI, and curl examples.
Architecture
Binaries, layout, domain tables, and how handlers compose.
API
Endpoints, envelope shape, and OpenAPI.
Operations
Azure Pipelines, Helm, Service Bus topology, and migrations on deploy.
What it owns
- Sample CRUD for
domain1anddomain2(POST/GET /v1/domain1,/v1/domain2, including paginated lists) - Per-domain outbox tables and a publisher in the API binary (Azure Service Bus in all environments, emulator locally)
- Shared platform types in
0001_platform.sql(event_visibilityenum) - Vendored Swagger UI and served OpenAPI spec
- Extra binaries from the same image:
flowstate, plusdomain1Listeneranddomain2Listenerwhich log each domain's fanout messages
What it does not own
Production business logic or authorization. Replace the example domains and migrations when copying;
keep internal/command/, internal/publisher/, and the handler patterns. Wire Cedar auth when
copying into a real service — see services/accounting for the current pattern.
New services follow
docs/decisions/0015-domain-scoped-outbox-and-table-prefixes.md:
0001_platform.sql holds shared types; each domain adds its prefixed tables and outbox in
0002_<domain>.sql.
Canonical service README: services/template/README.md.