Golang DDD Architecture
Use this skill to shape a Go service so it stays easy to change, test, and reason about as business logic grows.
Start Here
- Check whether the service is complex enough to justify the pattern.
- Keep the design smaller for simple CRUD or authentication flows where read and write shapes are mostly identical and business rules are thin.
- Use the full workflow when handlers keep growing
iftrees, models are reused across boundaries, or dependencies are hard to mock or untangle.
Workflow
- Inventory entry points and use cases.
- Start from HTTP handlers, gRPC services, CLI commands, message consumers, and scheduled jobs.
- Rewrite the supported operations in business language before moving code around.
- Draw the boundary map.
portsare inbound transport and serialization only.apporchestrates use cases.domainowns business rules and invariants.adapterstalk to databases, queues, external APIs, files, and other infrastructure.
- Enforce dependency direction.
domaindepends on nothing outside itself.appmay importdomainbut not concrete transport or adapter packages.portsandadaptersmay import inward layers.- Fix import cycles by moving interfaces inward or by splitting responsibilities, not by flattening everything into one package.
- Place interfaces next to the consumer.
- Define interfaces in the package that needs the behavior.
- Keep them narrow and use-case-oriented.
- Inject implementations from the composition root.
- Separate models that change for different reasons.
- Do not reuse one struct for DB rows, API responses, Pub/Sub payloads, and domain state unless their change cadence is truly the same.
- Accept data duplication when it removes coupling. DRY is usually more valuable for behavior than for data.
- Keep
mainboring.
- Use
mainas the composition root. - Wire repositories, clients, handlers, and configuration there.
- Do not hide business logic, validation, or workflow branching there.
- Leave the codebase more testable than you found it.
- Domain rules should be unit-testable without mocks.
- Application orchestration should be testable with tiny handwritten mocks.
- Adapter behavior should be covered with integration tests.
Use These References
- Read references/architecture-rules.md for layer rules, package layouts, and anti-patterns.
- Read references/naming-and-models.md when naming, model boundaries, or shared-struct tradeoffs are the hard part.
Deliverables
- a clear layer map or package plan,
- dependency direction that compiles without import-cycle hacks,
- constructors or wiring points in the composition root,
- explicit model boundaries,
- a short backlog of follow-up refactors if the system is too tangled for one pass.