Hexagonal architecture

From A Technological Wiki
Revision as of 11:01, 19 April 2025 by imported>Unknown user
Jump to navigation Jump to search

The Hexagonal Architecture, also known as the Ports and Adapters Pattern, was introduced by Alistair Cockburn. The primary goal of this architectural pattern is to allow an application to equally be driven by users, programs, automated tests, or batch scripts, and to be developed and tested in isolation from its eventual runtime devices and databases.

Three Main Layers

When working with hexagonal architecture we structure the code in three main concepts:

Application Layer

This is the outermost layer where all the primary actors (like users, external systems, etc.) interact with the system. The application layer contains:

  • Application services: They are responsible for coordinating application operations.
  • Use Cases: They group services to perform a certain action, such RegisterUser, it will use CreateUserService and SendRegisterEmailToUser
  • DTOs: Used for communication between the application and outer layers.
  • Responses: Used for communication between the application and outer layers.

Domain Layer

This is the heart of the system and contains everthing related with the bounded context. Check Domain Driven Design section to get further information

Infrastructure Layer

This is where all the components that provide support to the application and domain layers reside.

  • Frameworks and tools such as databases, web frameworks, etc.
  • Adapters that convert from a technology-specific format to a format the application can handle.
  • Repositories implementations (like database implementations of the repositories defined in the domain layer).

As we see in this image, layers can communicate from outer layers to inside ones, but not the other way around in order to preserve conceptual behaviour. This is for example, an object from the Domain layer can't use an object from the application layer.

Example of a Folder Tree Structure

/src

|-- $Context (API, Backoffice, etc)

|--|-- $Model (Order, User, etc)

|--|--|-- Application

|--|--|--|-- Services (atomic functionalities)

|--|--|--|--|-- $ServiceName

|--|--|--|--|--|-- ${ServiceName}Service.php

|--|--|--|--|--|-- ${ServiceName}DTO.php

|--|--|--|--|--|-- ${ServiceName}Response.php

|--|--|--|-- UseCases (group of services)

|--|--|-- Domain (aspects that relate to the context)

|--|--|--|-- Entities

|--|--|--|--|-- $entity.php

|--|--|--|-- Exceptions

|--|--|--|--|-- ${ExceptionCase}Exception.php

|--|--|--|-- ValueObjects

|--|--|--|-- Contracts

|--|--|--|--|-- ${Model}RepositoryInterface.php

|--|--|-- Infrastructure (Helpers used to develop funcionalities)

|--|--|--|-- UserInterface (User / Services entry points)

|--|--|--|--|-- Controllers

|--|--|--|--|--|-- ${ControllerCase}Controller.php

|--|--|--|--|-- Commands

|--|--|--|-- Repositories