Oksa Satya.

June 24, 2026 · 8 min read

Hexagonal Architecture in Go: Why the Domain Must Not Know About the Database

GoArchitectureHexagonalClean Architecture

Many developers hear 'hexagonal' and picture complex diagrams and endless folders. The essence is one sentence: business rules must not know where their data comes from. Here is why that discipline pays off in production systems like Dexova, and how to apply it in Go without overdoing it.

Dependencies flow inward

The rule is single and strict: the domain layer imports nothing from adapters or platform. The domain defines the ports (interfaces) it needs — e.g. a repository — and the outer layer implements them with pgx or whatever else.

The effect: use cases can be tested with a fake in-memory port implementation, with no PostgreSQL, no network. Testing payroll becomes about preparing input and checking output — not standing up the whole infrastructure.

Ports are contracts owned by the domain

A common mistake: defining the repository interface in the adapter package, 'close' to its implementation. That inverts the dependency direction. A port is a domain need, so it lives in the domain; the adapter conforms, not the other way around.

In Go this feels natural because interfaces are implicit — the domain declares small interfaces for exactly what it needs, and adapters simply satisfy them. Lean interfaces (one or two methods) are far easier to mock than a giant do-everything repository.

Don't over-engineer: hexagonal-lite

Hexagonal does not mean CQRS, event sourcing, and seven layers of abstraction for simple CRUD. For a solo dev or small team, it's enough to have: a pure domain (entities + ports + use cases), adapters (DB, HTTP, third parties), and a composition root that wires it together.

Signs of over-engineering: an interface with one implementation that will never have a second, a factory for a single product, an abstraction 'for later'. The rule: add a layer when the pain is real, not when you imagine it.

Summary

Hexagonal pays off not because the diagram is pretty, but because it makes business rules fast to test and infrastructure swappable without drama. Keep dependencies flowing toward the domain, let ports belong to the domain, and stop at the minimum number of layers that solves the problem.

Building something similar?

I take on projects and technical consulting around business systems.