← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Hexagonal Architecture (Ports & Adapters)

architecture PHP 5.0+ Advanced
debt(d5/e9/b9/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan, psalm, and deptrac — all specialist static analysis tools. Deptrac in particular is purpose-built to enforce architectural layer boundaries and would catch domain classes importing Doctrine ORM, Eloquent Model, or framework HTTP classes directly, exactly as noted in code_pattern. This is not caught by the compiler or default linters, but is detectable with deliberate specialist tooling.

e9 Effort Remediation debt — work required to fix once spotted

Closest to 'architectural rework' (e9). The quick_fix states 'Move all infrastructure concerns (DB, HTTP, email) behind interfaces defined in your domain — the domain core should have zero imports from framework or library namespaces.' This is not a single-line patch; it is a fundamental restructuring of the entire application's dependency graph. Common mistakes confirm that ports, adapters, domain layers, and framework coupling are all intertwined. Adopting or correcting hexagonal architecture means rethinking and rewriting the system's structural shape — a full architectural rework.

b9 Burden Structural debt — long-term weight of choosing wrong

Closest to 'defines the system's shape' (b9). The applies_to contexts span web, cli, and queue-worker — every context in a PHP application. The tags include architecture, design-pattern, testing, and solid. Hexagonal architecture is the most load-bearing architectural choice possible: every future feature, every infrastructure swap, every test strategy is shaped by whether this pattern is correctly applied. It is a rewrite-or-live-with-it commitment.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field explicitly states that competent developers confuse hexagonal architecture with layered architecture. The two look superficially similar — both have layers — but hexagonal inverts dependencies rather than flowing top-down, which is the opposite of what layered-architecture experience would predict. Common mistakes reinforce this: developers place ports in the wrong layer and put business logic in adapters, all because the mental model from familiar layered patterns misleads them.

About DEBT scoring →

Also Known As

ports and adapters hexagonal clean architecture

TL;DR

Isolates application core logic from external systems (HTTP, databases, queues) via ports (interfaces) and adapters (implementations).

Explanation

Hexagonal Architecture (Alistair Cockburn, 2005) places the application core at the centre and defines Ports — interfaces the application exposes or depends upon — and Adapters — concrete implementations that connect the core to the outside world (web controllers, database repositories, message queue consumers). The core never depends directly on frameworks, databases, or HTTP. This means the domain and use case logic can be tested with in-memory adapters, and production adapters can be swapped without touching the core. It is conceptually similar to Clean Architecture and DDD's application layer.

Diagram

flowchart LR
    subgraph Core
        APP[Application Services]
        DOM[Domain Model]
        APP --- DOM
    end
    HTTP[HTTP / REST] -->|Input Port| APP
    CLI[CLI / Queue] -->|Input Port| APP
    APP -->|Output Port| DB[(Database Adapter)]
    APP -->|Output Port| EMAIL[Email Adapter]
    APP -->|Output Port| CACHE[Cache Adapter]
style APP fill:#6e40c9,color:#fff
style DOM fill:#6e40c9,color:#fff
style HTTP fill:#1f6feb,color:#fff
style CLI fill:#1f6feb,color:#fff

Common Misconception

Hexagonal architecture is just another name for layered architecture. Layered architecture has a strict top-down dependency flow. Hexagonal architecture inverts dependencies — all external concerns (HTTP, database, email) are adapters that plug into the application core via ports, making the core fully independent.

Why It Matters

Hexagonal architecture (Ports and Adapters) keeps business logic completely isolated from infrastructure — you can swap a MySQL database for PostgreSQL, or replace an HTTP API with a CLI, without touching domain code. It makes the application testable without any infrastructure running.

Common Mistakes

  • Putting framework-specific code (Eloquent models, Laravel Request) inside the domain layer.
  • Defining ports (interfaces) in the infrastructure layer instead of the application layer — this inverts the dependency.
  • Creating adapters that do more than translate between domain and infrastructure — business logic does not belong there.
  • Over-engineering small applications with hexagonal architecture — the value appears at the scale where infrastructure changes.

Code Examples

✗ Vulnerable
// Application service reaching into HTTP request:
class CreateOrderUseCase {
    public function execute(Request $request): Response { // Coupled to HTTP!
        $data = $request->json();
        // ...
        return response()->json($order);
    }
    // Should accept a plain DTO, not an HTTP Request object
}
✓ Fixed
// Domain (centre) — no framework imports
class OrderService {
    public function __construct(
        private OrderRepositoryPort $orders, // Port (interface)
        private PaymentPort         $payment, // Port (interface)
    ) {}
    public function place(Cart $cart): Order { ... }
}

// Adapter (outside) — implements the port
class EloquentOrderRepository implements OrderRepositoryPort {
    public function save(Order $o): void { EloquentOrder::create($o->toArray()); }
}

class StripePaymentAdapter implements PaymentPort {
    public function charge(Money $amount): ChargeId { ... }
}

// The domain layer never knows if it's talking to Stripe or a test fake

Added 15 Mar 2026
Edited 22 Mar 2026
Views 79
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 2 pings W 1 ping T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 2 pings S 2 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
ChatGPT 23 Amazonbot 18 Perplexity 15 Google 9 Ahrefs 2 Unknown AI 2 SEMrush 2 Majestic 1
crawler 72
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: High
⚡ Quick Fix
Move all infrastructure concerns (DB, HTTP, email) behind interfaces defined in your domain — the domain core should have zero imports from framework or library namespaces
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Domain classes importing Doctrine ORM Eloquent Model or framework HTTP classes directly
Auto-detectable: ✓ Yes phpstan psalm deptrac
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update

✓ schema.org compliant