Hexagonal architecture (a.k.a. Ports & Adapters) transforms how we structure Java applications: it isolates core domain logic from frameworks, databases, and UIs so the heart of the app stays testable, stable, and easy to evolve. Below is a concise, thought-provoking exploration you can share or expand into a blog post or social thread.
: Contains technical implementations like REST controllers and database repositories. Key Benefits
The service layer inside the core coordinates business execution. It implements the inbound port and utilizes the outbound port.
Interfaces called by external clients (e.g., a web controller) to trigger business logic.
Adapters are the outer layer. They handle plumbing, frameworks, and specific infrastructure technologies. Hexagonal architecture (a
The outside world (Web, Database, Message Queue) connects via "Ports" (interfaces) and "Adapters" (implementations).
You can swap Spring Boot for Quarkus, Micronaut, or plain Java without changing business logic.
@PostMapping("/accounts/id/withdraw") public void handle(@PathVariable Long id, @RequestBody MoneyDto dto) withdrawUseCase.withdraw(id, dto.toMoney());
</dependencies>
package com.example.order.ports.outbound; import com.example.order.domain.Order; public interface OrderRepositoryPort void save(Order order); Use code with caution. 3. The Core Service (Implementing Inbound Ports)
: The innermost layer containing core business rules through entities and value objects. It remains completely technology-agnostic and has no dependencies on other layers. Application Hexagon
Interfaces that expose the application's use cases to the outside world (e.g., PlaceOrderUseCase ).
The application service coordinates the interaction between the ports and adapters: Interfaces called by external clients (e
: Swap out Spring Boot, Quarkus, or databases without altering core logic.
Notice: WithdrawController doesn't know about a database. The WithdrawMoneyPort is the boundary. This is the magic that the 2021 PDF resources emphasized.
Next, we create the inbound use-case interface and the outbound repository interface.