Optivem Journal

Optivem Journal

Hexagonal Architecture

Hexagonal Architecture: Don't Follow the Diagram

Don't create a class just because the Hexagonal Architecture diagram has one

Valentina Jemuović's avatar
Valentina Jemuović
Aug 20, 2026
∙ Paid

📅 Join me: Clean Architecture for Backend Developers on Wed 26th Aug, 5:00 - 6:30 PM (CEST)


The first time you see Hexagonal Architecture, it can feel like a lot.

Schedule a shipment.

You're used to something like: ShipmentHttpController, talking straight to the ORM and the FedEx API. One class, two integrations.

Then you look at the Hexagonal Architecture version of the same feature:

  • driving adapter (ShipmentHttpController)

  • driving port (ScheduleShipmentUseCase)

  • the hexagon itself (Shipment, Address, PackageDetails, ShipmentRepository, CourierGateway)

  • driven adapters (SqlShipmentRepository, FedExCourierGateway).

And here’s where things can get out of hand.

You start creating all of these classes before you actually need them.

The Starting Point

🚫 Problem: No pain yet

One feature, one caller, one integration on each side.

✅ Solution: Ship it as a single class

There’s nothing to abstract until something actually hurts.

One class handles the HTTP request, runs the validation, talks to Postgres through JPA, and calls the FedEx SDK directly. No ports, no adapters, no domain model.

This isn't the design we'd want to keep forever: it’s slow to test and it’s going to get worse as more logic lands in it — but it hasn’t gotten worse yet.

Step 1 — Driven Ports Keep I/O Out of the Way

🚫 Problem: Tests are slow

Every test hits a real Postgres instance and the real FedEx test instance, so they’re slow, and the test instance goes down more often than the code changes.

✅ Solution: Use driven ports for I/O

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 Valentina Jemuović, Optivem · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture