Some text some message..
Back Hexagonal Architecture: Ports and Adapters architecture. 07 Aug, 2025

Let's dive into the Hexagonal Architecture, also known as the Ports and Adapters architecture. It’s a popular system design pattern used for creating maintainable, flexible, and decoupled software applications.


🌟 Hexagonal Architecture (Ports and Adapters) – Detailed Explanation

Definition

The Hexagonal Architecture is a software architecture pattern that promotes separation of concerns by isolating the core logic of your application (called the Domain) from external systems like databases, UIs, APIs, or other services using Ports and Adapters.


🧩 Core Components of Hexagonal Architecture

I'll present this as a colorful visual layout, which you can imagine or draw:

     [ External World: CLI / Web / Mobile App / API ]
                         |
                    [Adapter]
                         |
                    [  Port  ]
                         |
                 ┌────────────────┐
                 │   Application  │
                 │     Core       │
                 │ (Domain Logic) │
                 └────────────────┘
                         |
                    [  Port  ]
                         |
             [Adapter: DB / External APIs]

🔹 1. Application Core (Domain Layer)

  • 💡 What it is: The heart of the system that contains business rules and logic.

  • No dependencies on external frameworks.

  • Pure Python (or any language) classes and functions.

  • 🔒 Keeps your system robust and testable.


🔹 2. Ports

  • 🌀 What it is: Interfaces that define how the application talks to the outside world.

  • 🔁 Inbound Ports: Accept inputs (e.g., service interfaces, commands).

  • 📤 Outbound Ports: Define what the core needs from external systems (e.g., database read/write, API calls).

Think of Ports as plugs — defining what needs to be connected without caring how it works.


🔹 3. Adapters

  • 🔧 What it is: Implementations of Ports.

  • ✨ Translates between the format used by external systems (REST, SQL, UI events) and what the core logic understands.

  • 🧱 Inbound Adapters: e.g., Controllers, CLI, Event Handlers.

  • 🧱 Outbound Adapters: e.g., Repositories, Web Clients, Message Brokers.


🎯 How It Helps

Feature Benefit
🔄 Loose Coupling Easily swap UI, DB, or external services
🧪 Testability Core can be tested in isolation
📦 Plug-and-Play Add new interfaces without changing core logic
⚙️ Maintainability Easier to manage and evolve over time

💻 Example: A Banking Application

🧠 Core (Application Logic)

# port interface
class AccountService:
    def deposit(self, account_id: str, amount: float): pass
    def withdraw(self, account_id: str, amount: float): pass

🔌 Adapter (REST API)

@app.route('/deposit', methods=['POST'])
def deposit():
    account_id = request.json['account_id']
    amount = request.json['amount']
    account_service.deposit(account_id, amount)
    return "Success"

🛢️ Adapter (Database)

class AccountRepository:
    def save(account): ...
    def load(account_id): ...

🌈 Summary Diagram (Color-coded Roles)

🎨 Layer 🔍 Responsibility 🔌 Examples
🧠 Core Business rules Account, TransactionService
🚪 Ports Define how core talks to outside IAccountRepository, IServicePort
🔧 Adapters Implement interfaces REST Controller, SQLAlchemy Repository
🌍 External Tools/Interfaces that use the app UI, DB, External APIs

🧠 Key Principles

  • Dependency Inversion: Core doesn't depend on external layers.

  • Open-Closed Principle: Add functionality via new adapters, not modifying core.

  • DRY and SRP: Keeps each part of the system focused.


📘 Bonus: When to Use Hexagonal Architecture?

✅ Recommended for:

  • Large or long-term systems

  • Systems with multiple interfaces (e.g., API + CLI + Scheduler)

  • Domain-driven applications

  • Systems requiring testability