Overview

2 WriteFlow's wake-up call: When good architecture intentions aren't enough

WriteFlow begins as a sensible layered monolith, but growth quickly exposes its limits: business rules, framework annotations, persistence concerns, and API concerns all accumulate in the same places, making the system slow to test and hard to evolve. The chapter uses this realistic case to show that the problem is not bad engineering, but architecture that no longer matches the system’s needs. Hexagonal architecture is presented as the remedy because it separates the core from infrastructure and keeps dependencies pointed inward.

The chapter then explains how a request moves through the hexagon: a primary adapter translates incoming HTTP into a core-level command, an input port defines the use case, a handler orchestrates business flow, and output ports let the core ask the outside world for data or persistence without knowing implementation details. Secondary adapters fulfill those requests, while the adapter layer also maps core results back to external responses. This structure makes the core easy to test, infrastructure easy to swap, and boundaries explicit instead of implicit.

Finally, the chapter maps a safe migration path for moving a real system to this style without a risky rewrite. The WriteFlow team extracts domain logic, defines ports, wraps old code behind facades, refactors orchestration into pure handlers, and replaces adapters one at a time while verifying boundaries. It also highlights common mistakes, such as putting business logic in adapters or defining ports that merely mirror JPA methods, and stresses the importance of stakeholder buy-in, incremental delivery, and automated boundary checks to keep the architecture honest.

WriteFlow v1: layered architecture showing Article entity carrying @Entity, @JsonProperty, and @Table annotations simultaneously. Arrows show how a single change to Article ripples through all layers.
A single HTTP POST /articles request flowing through WriteFlow's hexagonal architecture: REST adapter → input port → handler → output port → secondary adapter. Arrows show both the flow of control and the direction of dependencies, which always point inward toward the core.
The request flow from figure 2.2, annotated with component type labels: Primary Adapter, Input Port, Handler, Domain Entity, Output Port, Secondary Adapter. Each label links to the corresponding row in table 2.1.
The WriteFlow five-phase migration map: Phase 1 Extract → Phase 2 Define → Phase 3 Wrap → Phase 4 Refactor → Phase 5 Replace. Each phase box contains its primary goal and a chapter reference.

Summary

  • WriteFlow's migration from a tightly coupled layered architecture to hexagonal architecture followed five incremental phases—Extract, Define, Wrap, Refactor, Replace—each delivering working software before the next phase began. No big bang rewrite. No production risk.
  • The migration decision is as much a stakeholder conversation as a technical one. The strongest argument is a working prototype showing millisecond handler tests and a successful adapter swap, not a diagram. Lead with numbers, not principles.
  • Hexagonal architecture produces six standard component types: primary adapters, input ports, handlers, domain entities, output ports, and secondary adapters. Table 2.1 maps each one to its responsibility and to the chapter where it is built in this book.
  • For teams coming from layered architecture, the components are familiar (controllers, services, repositories) but the critical difference is ownership. The core defines the port interfaces. Adapters conform to the core's terms. That single reversal, the Dependency Inversion Principle in practice, is what makes the core independently testable and the adapters independently swappable.
  • The two most common migration mistakes are business logic leaking into adapters and ports designed around infrastructure methods rather than domain needs.
  • ArchUnit is not optional. Without automated boundary enforcement, dependency leaks return within weeks.

FAQ

What problem did WriteFlow’s original layered architecture run into?The original layered monolith worked well at first, but as the product grew, business pressures added more concerns to the same classes. The Article entity ended up carrying HTTP, persistence, and validation responsibilities together, which made tests slow and changes risky.
Why did the team decide that good architecture intentions were not enough?Because the system had outgrown the structure that originally fit it. Even though the team made sensible choices early on, later requirements were handled locally and quickly, causing architecture drift and making the codebase harder to evolve.
How does a request flow through WriteFlow’s hexagonal architecture?An HTTP request enters through a primary adapter, is translated into a command, calls an input port, is handled by a core handler, which may use output ports to reach secondary adapters, and then the result flows back outward to the controller for HTTP response mapping.
What is the role of the primary adapter in WriteFlow?The primary adapter receives external requests such as HTTP, CLI, or Kafka events and translates them into input port calls. It owns transport concerns like JSON mapping and HTTP status codes, but contains no business logic.
What does the handler do in hexagonal architecture?The handler implements the input port and orchestrates the use case. It validates input, coordinates domain objects, and calls output ports when needed. It has no framework annotations and depends only on port interfaces.
Why are output ports important?Output ports let the core express what it needs from the outside world without knowing how that need will be fulfilled. They keep infrastructure details out of the core and make the application easier to test and swap between implementations.
What is the biggest benefit of hexagonal architecture for reusable components?Reusable core components can be moved to new contexts with minimal change. For WriteFlow, the same CreateArticleUseCase could serve both a REST API and a Kafka consumer; only the adapter had to change.
What are the five migration phases WriteFlow followed?The phases were: 1) Extract the domain, 2) Define the ports, 3) Wrap existing code as facade adapters, 4) Refactor into handlers, and 5) Replace and verify. Each phase preserved working software and avoided a big bang rewrite.
What was the main trap in Phase 2: defining ports?The team initially made ports too close to the existing JPA repository methods. That created JPA-shaped abstractions instead of ports that reflected what the core actually needed. Ports should be shaped by use cases, not by infrastructure APIs.
What common mistakes did WriteFlow nearly make during migration?Two major mistakes were putting business logic in adapters and making ports mirror implementation details. Both lead to duplicated rules and leaky abstractions. The chapter recommends keeping validation in the domain and designing ports around business needs, not technology.

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
  • Clean Applications with Hexagonal Architecture 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
  • Clean Applications with Hexagonal Architecture ebook for free