Overview

1 Taming complexity with hexagons

Hexagonal architecture is presented as a practical response to the way software systems quietly degrade over time. Rather than failing from one dramatic mistake, codebases usually become hard to change because of accidental complexity: frameworks, databases, transport formats, and external services creep into the business core until every small change ripples everywhere. The chapter argues that the real problem is weak boundaries, and that architecture should defend the parts of the system that need to stay stable as the rest evolves.

The central idea is to keep the application core pure, testable, and independent by making dependencies point inward. The core defines ports, or interfaces, that describe what the application can do and what it needs; adapters live outside the core and implement those contracts for REST APIs, databases, queues, and other technologies. This is powered by dependency inversion, which lets business logic depend only on abstractions, making the core easy to test, infrastructure easy to swap, and domain rules protected from leakage.

The chapter also shows how the pattern works in practice through an article-creation example: a controller maps an HTTP request into a command, an input port hands it to a handler, the handler applies domain rules and calls output ports, and driven adapters handle persistence or external lookups. The result is a system with explicit boundaries, typed error handling, and infrastructure isolated at the edges. The chapter closes by noting that hexagonal architecture is especially valuable for systems with many integrations and long lifespans, but it is not always the right choice for small CRUD apps or simple prototypes where its extra structure may be unnecessary.

Without an architectural structure, technical debt compounds exponentially. Hexagonal architecture keeps costs manageable by isolating change impact.
The core defines ports (interfaces). Adapters implement them. Dependencies always point inwards.
In traditional, layered architectures, dependencies flow downwards, whereas in the hexagonal architecture, dependencies flow inward.
Metaphor of lasagna leaking technical constraints of the data model into all the layers.
Abstraction of a fake boundary pretending to protect the core and failing to do so.
Hexagonal Architecture for Article creation -- complete component diagram with flow.

Summary

  • Hexagonal Architecture isolates core business logic from external concerns using Ports (interfaces) and Adapters (implementations), with dependencies always flowing inward via the Dependency Inversion Principle.
  • The pattern solves accidental complexity, the maintainability decay that plagues growing codebases, by keeping domain logic framework-agnostic, testable in isolation, and swappable at the boundaries.
  • Real-world use cases include SaaS products needing multiple interfaces, technology migrations without touching business logic, and testing transformations from slow integration tests to fast unit tests.
  • Think of it as a pipeline that follows a clear flow: any request (in whatever flavor) arrives at a Primary Input Adapter, which calls an Input Port (an interface). The Handler implements it by orchestrating validation, domain creation, and persistence or any other external dependencies via Output Ports (again, interfaces). Results flow back as typed Either<Error, Void|DTO> values -- no hidden exceptions.
  • Key patterns include the Always-Valid Domain Model, functional error handling with Either, CQRS, and architectural testing with ArchUnit. The book uses Java + Spring Boot + Vavr + additional aid libraries, but the principles apply universally to them.
  • This is pragmatic architecture, not dogma. You will learn when to apply patterns rigorously, when to compromise, and how to introduce hexagonal architecture gradually to legacy codebases.

FAQ

What is hexagonal architecture in simple terms?

Hexagonal architecture is a way to structure software so the business core stays protected from frameworks, databases, user interfaces, and external services. The core defines what it needs through ports, and external technologies connect through adapters.

Why is hexagonal architecture important for maintainable software?

It keeps change local by preventing infrastructure concerns from leaking into business logic. That makes the system easier to test, refactor, and evolve as requirements or technologies change.

What problem does hexagonal architecture solve?

It solves accidental complexity caused by hard-wiring components directly to databases, APIs, frameworks, and each other’s internals. By isolating the core behind explicit boundaries, it stops small changes from rippling through the whole codebase.

What are ports in hexagonal architecture?

Ports are interfaces defined by the core. Input ports describe what the application can do, while output ports describe what the application needs from the outside world, such as persistence or external services.

What are adapters in hexagonal architecture?

Adapters are concrete implementations outside the core that connect external technologies to ports. Driving adapters, like REST controllers, call input ports; driven adapters, like JPA repositories or API clients, implement output ports.

What does dependency inversion mean in this architecture?

It means the core depends only on abstractions it owns, and adapters depend inward on those abstractions. Instead of the core knowing about JPA, REST, or Kafka, those technologies conform to the core’s contracts.

How does hexagonal architecture improve testing?

Because the core is pure and framework-free, it can be tested with plain unit tests and mocked ports. This avoids expensive full application context tests and makes business logic tests run quickly.

When should I use hexagonal architecture?

It is most valuable for systems with growing complexity, many integrations, long lifespans, or frequent technology changes. It is especially useful when you want high testability and easy adapter swapping.

When might hexagonal architecture be overkill?

For small CRUD apps, prototypes, or stable systems with little expected change, the extra structure may slow development without providing much benefit. In those cases, simpler layered approaches may be more practical.

How does a request flow through a hexagonal architecture?

A request enters through a driving adapter, is translated into a command, passes through an input port into a handler, applies domain rules, calls output ports as needed, and then returns a result back through the adapter. All dependencies still point inward toward the core.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Decoupling by Design ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Decoupling by Design ebook for free