Optivem Journal

Optivem Journal

Hexagonal Architecture

Hexagonal Architecture: Your Driven Ports Are Leaking Infrastructure

Clean Interfaces, Leaky Abstractions. Your driven ports look clean — but they're leaking infrastructure into your domain. Your domain is coupled to infrastructure!

Valentina Jemuović's avatar
Valentina Jemuović
Apr 23, 2026
∙ Paid

You followed the pattern.

You split your domain from infrastructure.
You added interfaces.
You called them “driven ports.”

It looks clean.

But then:

  • Your tests are full of mocks

  • Refactoring breaks everything

  • Your domain still feels… tied to something

And you can’t quite explain why.

Driven Ports Gone Wrong

Most developers know they need interfaces between their domain and infrastructure. But the mistake isn’t forgetting to add them.

It’s adding them at the wrong level of abstraction.

Your driven port might look clean on the surface — but if infrastructure concepts are leaking through, your domain is already compromised.

What a Driven Port Should Do

A driven port isn’t:

  • a wrapper around a framework class

  • a thin layer over a database driver

  • a generic interface that exposes how things work underneath

A driven port is:

  • something the domain needs to get its work done

  • a boundary expressed in domain language

  • a contract that hides how things are implemented

The key question: does this interface expose what the domain needs, or how the infrastructure works?


🚀 Register now: Acceptance Testing Workshop
Get 100 EUR off with code EARLYBIRD100


❌ Driven Ports That Leak Infrastructure

interface OrderRepository {
    ResultSet executeQuery(String sql);
    void executeBatch(String[] statements);
}

interface PaymentGateway {
    HttpResponse post(String url, Map<String, String> headers, String jsonBody);
}

interface NotificationService {
    void sendRawMessage(String host, int port, String payload);
}

interface ProductCatalog {
    Map<String, AttributeValue> getItem(String tableName, Map<String, AttributeValue> key);
}

What’s wrong here?

  • OrderRepository exposes SQL — the domain now knows it’s a relational database

  • PaymentGateway exposes HTTP — the domain now knows it’s a REST API

  • NotificationService exposes host and port — the domain now knows about transport protocols

  • ProductCatalog exposes AttributeValue — the domain now knows it’s DynamoDB

Your domain is shaped by your infrastructure. Change the database, the API, or the message broker — and your domain code has to change too.

That’s the opposite of decoupling.

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