A production-ready Golang backend template built with Domain-Driven Design (DDD), Vertical Slice Architecture, CQRS, Clean Architecture, and Modular Monolith principles.
- DDD - Entities, Value Objects, Domain Services, Specifications, Domain Events
- CQRS - Separate Command and Query handlers
- Clean Architecture - Strict dependency direction: Interface → Application → Domain ← Infrastructure
- Modular Monolith - Each module is independent with its own domain, application, infrastructure, and interface layers
- Vertical Slice - Each feature is a self-contained slice through all layers
| Component | Technology |
|---|---|
| Language | Go 1.22+ |
| HTTP | Chi Router |
| DI | Uber Fx |
| Database | PostgreSQL |
| Query | SQLC |
| Migration | Goose |
| Config | Koanf |
| Logging | Zap |
| Validation | go-playground/validator |
| Auth | JWT |
| Cache | Redis |
| Messaging | NATS |
| Tracing | OpenTelemetry |
| Testing | Testify + GoMock |
| Container | Docker + Docker Compose |
# Start all services
make docker-up
# Run migrations
make migrate-up
# Generate SQLC code
make sqlc
# Start the API server
make run| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/todos | Create a todo |
| GET | /api/v1/todos | List all todos |
| GET | /api/v1/todos/{id} | Get a todo by ID |
| PUT | /api/v1/todos/{id} | Update a todo |
| DELETE | /api/v1/todos/{id} | Delete a todo |
| PATCH | /api/v1/todos/{id}/complete | Complete a todo |
| GET | /api/v1/todos/search?q= | Search todos |
| GET | /health | Health check |
| GET | /ready | Readiness check |
The EventBus is switchable between in-memory and NATS JetStream via config:
events:
driver: memory # "memory" (default) or "nats"| Driver | Delivery | Persistence | Cross-instance |
|---|---|---|---|
memory |
Synchronous, at-most-once | None | No |
nats |
At-least-once via Ack/Nak | File-backed stream | Queue group (one worker per message) |
When driver: nats, events are published to a JetStream stream (events.>) and consumed via a push consumer with queue group event-bus. Handlers that return an error trigger Nak(), causing infinite redelivery.
See Architecture.md
See API.md
See Development.md
See Deployment.md