Hexagonal Architecture ⬡

Hexagonal Architecture (also known as Ports and Adapters) takes the same core idea as Clean Architecture — isolate business logic from infrastructure — and gives it a more explicit mechanism: ports define what the application needs, adapters implement how those needs are fulfilled.

The model

Hexagonal Architecture

The application sits at the center with two types of boundaries:

  • Inbound ports — How the outside world talks to your application (HTTP controllers, CLI handlers, message consumers).
  • Outbound ports — How your application talks to external systems (database repositories, API clients, message publishers).

The ports are interfaces. The adapters are implementations. Your domain never knows whether it's talking to a real database or a test double — it only knows the port.

Why this model clicks

The strength of Hexagonal over a generic "layered architecture" is that it makes the direction of dependencies visually obvious. Inbound adapters call your application. Your application calls outbound ports. Nothing in the core reaches outward. The hexagon shape isn't just a diagram — it's a reminder that your application has multiple edges, each replaceable independently.

When to use it

Hexagonal works well when your application has multiple entry points (REST, gRPC, event consumers) or multiple external dependencies that might change (swap Postgres for DynamoDB, swap SQS for Kafka). The port/adapter model makes those swaps safe and testable.

For a single-endpoint, single-database service, it's typically more structure than you need.

Project structure

  • 📁 adapter
    • 📁 in
      • 📁 web
        • 📄 SendMoneyController.java (Entrypoint)
    • 📁 out
      • 📁 persistence
        • 📄 AccountMapper.java
        • 📄 AccountPersistenceAdapter.java (impl. LoadAccountPort)
        • 📄 ActivityRepository.java
        • 📄 AccountRepository.java
  • 📁 application
    • 📁 port
      • 📁 in
        • 📄 SendMoneyUseCase.java (Interface)
      • 📁 out
        • 📄 LoadAccountPort.java (Interface)
    • 📁 domain
      • 📁 model
        • 📄 Money.java
        • 📄 Account.java
      • 📁 service
        • 📄 SendMoneyService.java (impl. SendMoneyUseCase)

Sources