Hexagonal Architecture (Ports and Adapters)
Hexagonal Architecture, also known as Ports and Adapters, is an architectural pattern used in software design. It aims to create loosely coupled application components that can be easily connected to their software environment by means of ports and adapters.
1. The Core Concept
The main idea is to isolate the Application Core (business logic) from outside concerns (User Interface, Database, External APIs).
- The Hexagon: Represents the core application. It contains the domain objects and the business rules. It knows nothing about the outside world (no SQL, no HTTP).
2. Ports
Ports are the interfaces that allow data to enter or leave the application core. They define what the application can do or what it needs, without defining how.
Primary Ports (Driving)
These are the entry points. They define the use cases of the application.
- Example:
IUserServiceinterface with methods likeregisterUser().
Secondary Ports (Driven)
These are the exit points. They define what the application needs from the outside world to work.
- Example:
IUserRepositoryinterface with methods likesave()orfindById().
3. Adapters
Adapters are the concrete implementations that plug into the ports. They translate data between the format required by the application and the format required by the external technology.
Primary Adapters (Driving)
They trigger the application logic.
- REST Controller: Converts an HTTP request into a call to the
IUserService. - CLI: Converts command line arguments into a call to the
IUserService. - Test Suite: Calls
IUserServicedirectly to verify logic.
Secondary Adapters (Driven)
They are triggered by the application logic.
- SQL Adapter: Implements
IUserRepositoryto save data to a PostgreSQL database. - Email Adapter: Implements
IEmailServiceto send emails via SMTP. - Mock Adapter: Implements
IUserRepositoryusing an in-memory array for testing.
4. Why "Hexagonal"?
The shape is arbitrary, but a hexagon was chosen to visually suggest that an application can have multiple distinct sides (ports) for different types of interactions, rather than just a simple "top-down" layer structure.
5. Benefits
- Testability: You can test the core logic in isolation by plugging in Mock Adapters for the database or external services.
- Flexibility: You can swap out a database (e.g., MySQL to MongoDB) just by writing a new Secondary Adapter, without touching the core logic.
- Independence: The business logic doesn't depend on frameworks or UI.
programming/clean-architecture programming/solid-principles programming/software-testing-basics