Software Development

Hexagonal Architecture: The Ultimate Guide to Clean and Flexible Software Design

Hexagonal Architecture, also known as Ports and Adapters, is a software design pattern that isolates the core logic of an application from the external agents (such as databases, user interfaces, external APIs, etc.). The central idea is to make the core application logic independent of the external systems so that it can evolve and be tested easily without being tied to external dependencies.

In simpler terms, this architecture allows you to build applications that can be easily adapted to different environments and external tools.

Key Concepts

  1. Core Business Logic (the center of the hexagon):
    • This is the heart of the application where all business rules, domain logic, and use cases are defined. It’s isolated from any external concerns, meaning the core logic doesn’t directly interact with external systems like databases, UI, or external services.
  2. Ports:
    • Ports define the "contract" or "interface" that the application exposes to the outside world. Ports represent the operations the application can perform, or the way external systems can interact with the application.
    • There are two types of ports:
      • Inbound Ports (driven ports): These are the interfaces through which the application receives input (e.g., user actions, incoming API requests).
      • Outbound Ports (driving ports): These are the interfaces through which the application sends data or interacts with external systems (e.g., databases, third-party services).
  3. Adapters:
    • Adapters implement the ports and are the components that connect the core application logic to the external systems.
    • Inbound Adapters: These are the adapters that interact with the external systems and forward input to the application through the inbound ports.
    • Outbound Adapters: These are the adapters that communicate from the core business logic to the external systems, using the outbound ports.

Structure of Hexagonal Architecture

The hexagonal architecture consists of a central hexagon representing the core business logic surrounded by various ports and adapters. The outer layers represent the external systems such as the UI, database, or external APIs.

          +----------------------+
          |                      |
          |    Inbound Adapters  |<-->Inbound Ports (driven)
          |                      |
          +----------------------+
                   |
                   |
          +----------------------+
          |                      |
          |   Core Business      |
          |       Logic          |
          |                      |
          +----------------------+
                   |
                   |
          +----------------------+
          |                      |
          |    Outbound Adapters |
          |                      |
          +----------------------+
                   |
                   |
          +----------------------+
          |                      |
          |   External Systems   |
          | (e.g., DB, APIs)     |
          |                      |
          +----------------------+

How Hexagonal Architecture Works:
Inbound Adapter:

The inbound adapter is responsible for receiving requests from the outside world (e.g., HTTP requests, user inputs) and translating them into a format understood by the core business logic. It then invokes the corresponding port.

Core Logic:

The core logic contains the business rules, domain models, and use cases. It defines the operations through the inbound and outbound ports but doesn’t know how those operations are implemented or where they come from.

Outbound Adapter:

The outbound adapter is responsible for interacting with external systems (e.g., databases, external services) and fulfilling the operations requested by the core logic. It communicates using the outbound ports.

 

Benefits of Hexagonal Architecture:
Testability:

The core logic is independent of external systems, so it can be easily tested without requiring actual databases or external services. You can mock the adapters to test the core logic in isolation.

Flexibility:

You can easily swap out external systems without affecting the core logic. For example, you can switch to a different payment gateway or database with minimal changes to the core logic.

Separation of Concerns:

The core business logic is clearly separated from the details of external systems (e.g., UI, database), making the application easier to maintain and evolve.

Easier to Adapt to Different Interfaces:

Hexagonal architecture allows the same core logic to be used with different kinds of interfaces. For example, it could be used in a web application, a command-line interface, or a microservice.

 

Hexagonal architecture is a powerful design pattern that promotes clean separation of concerns, making applications more maintainable, flexible, and testable. It isolates the core business logic from external dependencies, allowing for easier adaptation and evolution of the system.

 

Diagram Components:

  1. Hexagonal Core Business Logic:
    • Core Business Logic (center of the diagram): The core business logic is the heart of the system. It contains the essential operations, business rules, and domain models for the application. This part of the system is independent of external technologies, allowing it to focus purely on the business use cases and operations. For example, in an e-commerce application, this would be the logic for managing orders, payments, inventory, etc.
  2. Inbound and Outbound Ports:
    • Inbound Ports (or driven ports):
      • These represent the entry points to the core business logic. In this diagram, they are labeled as "Inbound Parts."
      • The inbound ports act as the "interfaces" that define the operations that can be performed on the core business logic. They could represent API endpoints, user interface actions, or other external inputs.
      • For example, an inbound port could represent a request to place an order in an e-commerce app.
    • Outbound Ports (or driving ports):
      • These represent the exit points where the core logic communicates with external systems (databases, third-party services, etc.). In the diagram, this is labeled as "Outbound Parts."
      • The outbound ports are responsible for sending data, processing results, and interacting with external systems such as databases, APIs, or services.
      • For example, an outbound port could represent the interaction with an external payment gateway or saving order information to a database.
  3. Adapters:
    • Inbound Adapters (or inbound parts):
      • These are the components that implement the inbound ports. In this diagram, they are labeled as "Inbound Ackgrens" (potentially meant to represent adapters for accepting inputs).
      • In a real application, an inbound adapter could be an API controller, a UI controller, or any interface that receives user input and forwards it to the core business logic through the inbound port.
      • For instance, an API controller handling HTTP requests from users would be an inbound adapter that passes data to the core logic via inbound ports.
    • Outbound Adapters (or outbound parts):
      • These components implement the outbound ports. In this diagram, they are labeled as "Outbound Parts."
      • An outbound adapter could interact with external systems such as databases, payment gateways, or messaging queues. It takes results from the core logic and sends them to external systems.
      • For example, a database adapter might handle writing data to a relational database, while a payment gateway adapter would call an external API to process payments.
  4. External Systems:
    • The far-right side of the diagram is labeled External Systems, which represent the outside world—services or systems that interact with your application via the outbound adapters.
    • These could be things like:
      • Databases (e.g., relational or NoSQL databases)
      • Third-party APIs (e.g., payment services, weather services)
      • External messaging queues or services
    • The solid arrow from "Outbound Parts" to "External Systems" indicates that the core logic sends information to these systems.

Flow of Data:

  1. Inbound Flow:
    • External Systems/Interfaces (like a UI or API request) send data to the Inbound Adapters (e.g., a REST API Controller).
    • The inbound adapter processes this input and passes it through the Inbound Port into the Core Business Logic. The core logic then handles the request, applies the business rules, and processes the data.
  2. Outbound Flow:
    • Once the core logic has processed the input and performed necessary operations (e.g., placing an order), it needs to interact with the external world.
    • The Core Business Logic communicates with the Outbound Ports (defining the necessary operations like saving to the database, calling a third-party service, etc.).
    • The Outbound Adapters implement these ports and send the necessary data to External Systems (such as saving data to a database or calling an external API).
  3. Decoupling:
    • The core business logic remains decoupled from the external systems, meaning the system can easily adapt to changes in the external systems (e.g., swapping databases or payment gateways) without requiring changes to the core logic.

About author

author image

Amrit panta

Fullstack developer, content creator



Scroll to Top