Skip to main content

Project structure

The five layers

LayerContainsMay depend on
L0 kernelDomain values, platform errors, identity, pagingStandard library and L0
L1 portsRepository and outbound-client interfacesL0
L2 applicationUse cases and workflow orchestrationL0 and L1
L3 adaptersHTTP, SQL, events, search, object storageInward layers and platform adapters
L4 compositioncmd/serverEvery layer for wiring only

Dependencies point inward. Domain and application code do not import router, pgx, Redis, AMQP, Elasticsearch, S3, or Kubernetes types.

Standard tree

cmd/server/main.go
internal/
domain/
service/
api/
repository/postgres/
client/
config/
db/
migrations/
embed.go
configs/config.yaml
openapi/
Dockerfile

Put an interface next to the application component that consumes it. Put its concrete adapter under repository or client. Keep generated code in a named package and never edit it manually.

Ownership questions

Before creating a package, ask:

  • Which domain owns the behavior and state?
  • Is this service-specific or shared runtime policy?
  • Which layer should know the vendor?
  • Who constructs and closes the resource?
  • What is the smallest API another package needs?

Cross-cutting transport, configuration, errors, paging, SQL, cache, events, identity, health, and lifecycle belong in dx-common-go/platform. Domain behavior remains in the service.

Internal and public

Use internal for service implementation. Public APIs are HTTP/OpenAPI, events, and deliberate Go modules—not exported service packages. This preserves freedom to refactor inside a service.

Exercise

Take one service and draw every import edge for a request. Flag an outward import from application code or a package called utils. Propose the narrow port and composition change that removes it.

Check yourself

  • Why is composition the only layer allowed to know all implementations?
  • Where does an outbound catalogue-client interface live?
  • When should code move to dx-common-go?
  • What boundary prevents cross-service Go imports?