Hexagonal, Clean and Onion Architectures
What is the problem?
How to maintain system integrity and ensure easy adaptability when business rules or external interfaces change?
Context: Communication with infrastructure and management of adapters

We are designing an e-commerce application and it needs to handle payment transactions for customer orders. Our need is to be able to integrate different payment providers such as PayPal, Stripe quickly and easily. Furthermore, as the business grows, it should have the ability to adapt to new payment providers and this should not affect our core business domain. To meet these requirements, we need to use a specific architectural approach.
Approach One: Hexagonal Architecture

Objective and Basic Principles
The Hexagonal Architecture, suggested by Alistair Cockburn, is a design approach intending to manage the interaction between the internal and external parts of an application. This architecture is utilized to separate the core business logic (domain) of the application from its interactions with the infrastructure, user interface, and other external services. This abstraction provides the application with a modular and independent structure, which increases its testability.
Hexagonal Architecture: A Detailed Breakdown of the Three Fundamental Layers
Application Layer — This layer manages the interaction with users and external systems and includes communication channels such as APIs and user interfaces. It communicates with the domain and infrastructure layers through ports.
Domain Layer — This layer contains the core business logic and business rules. It processes requests coming from the application layer, performs necessary operations, and executes domain services using data coming from the infrastructure layer.
Infrastructure Layer — This layer contains technologies and services that enable interaction with the outside world. Database access, external APIs, messaging services, and other infrastructure components are included in this layer. This layer provides service to the domain and application layers through adapters.
Managing Dependencies
Hexagonal Architecture guides the dependencies from external layers inward, making the domain layer independent of the outer layers and enhancing its testability. Dependency management is implemented based on the Dependency Inversion Principle, ensuring that modifications in the infrastructure and application layers don’t impact the domain layer.
Advantages:
- Infrastructure Communication and Adapter Management: Hexagonal Architecture provides more control and flexibility in managing communication with infrastructure and adapters.
- Testability: The separation of inner and outer layers facilitates the writing of unit tests and integration tests.
- Modularity: Hexagonal Architecture allows for treating different parts of the application separately, making the code more comprehensible and manageable.
- Flexibility: When new features need to be added or existing ones need to be altered, Hexagonal Architecture makes these changes easier.
- Isolation of Dependencies: This architecture ensures that changing infrastructure services has a minimal effect on the rest of the application.
Disadvantages:
- Complexity: Hexagonal Architecture can bring unnecessary complexity for simpler projects.
- High Initial Cost: Setting up this kind of architecture initially may require more time and resources.
- Over Abstraction: While abstraction is generally a good thing, in Hexagonal Architecture, over abstraction can sometimes lead to complexity.
Context: Prioritizes a more layered structure and management of intertwined dependencies

Imagine a social media application. In this application, there are complex workflows and processes carried out at different layers to manage users’ posts, comments, and friend requests.In a social media application, there are many things a user can do. To properly develop these new features, it’s essential to design our service with the right architectural structure to ensure its flexibility.
Approach Two: Clean Architecture

Objective and Basic Principles
The Clean Architecture, proposed by Robert C. Martin, aims to separate an application’s business rules from its external interfaces and dependencies. The main intent is to ensure the application’s core remains unaffected by changes in external frameworks, databases, and user interfaces. This architectural approach allows for a decoupled, scalable, and easily testable software structure.
Clean Architecture: A Detailed Breakdown of the Fundamental Layers
Entities Layer — These are the central objects representing the core business rules of the application. They remain unaffected by external entities and define the primary business logic.
Use Cases Layer — This layer outlines the specific operations and functions the application can perform, based on the entities. It processes the requests from the outer layers and interacts with entities to perform its tasks.
Interface/Adapters Layer — This layer converts data from a format most convenient for the use cases and entities to a format most convenient for some external agency such as a database or a web server.
Framework and Drivers Layer — The outermost layer, this is where web frameworks, database drivers, and other tools are implemented. This layer interacts directly with external systems and databases.
Managing Dependencies
In Clean Architecture, dependencies point inwards. The innermost layers are the most stable, and outer layers depend on them, ensuring that changes in frameworks, UI, or databases have minimal effect on business logic. The Dependency Inversion Principle plays a crucial role in this, where high-level modules define abstractions, and low-level modules implement them.
Advantages:
- Intertwined dependencies: Clean Architecture offers enhanced utility over Hexagonal Architecture in managing intertwined dependencies, ensuring a more structured and streamlined approach to handling complex relationships within the application.
- Testability: With the separation of concerns, writing unit tests becomes more straightforward, especially for business rules
- Maintainability: The modular structure ensures easy maintenance as changes to one layer have minimal effects on others.
- Flexibility: New frameworks or tools can be introduced without affecting the core business logic
- Isolation of Dependencies: This architecture ensures that changing infrastructure services has a minimal effect on the rest of the application.
Disadvantages:
- Complexity: For small projects, Clean Architecture might introduce unnecessary complexity.
- High Initial Cost: Initially setting up Clean Architecture might demand more time and resources.
- Over Abstraction: Just as with Hexagonal Architecture, over abstraction can lead to complications if not implemented judiciously.
Context: Prioritizes an intense focus on the Domain. Essentially, all other layers are organized around the Domain Model.

Imagine that you are working in a domain with complex core and business processes, such as Coupons. You need to create Domain-Focused Developments and Services. At the same time, the complexity of this system will increase with continuous new requirements and backlogs. Therefore, these developments should be easy to maintain, modular, flexible, and quick to test. Additionally, your domain should not be influenced by external factors. This is where applying DDD becomes inevitable for us. When using a layered architecture that focuses on the domain, you’re good to go. Here stands the Onion Architecture.
Approach Three: Onion Architecture

Objective and Basic Principles
The primary goal of Onion Architecture is to place the application’s core business logic at the center of the application, with other components interacting with it through well-defined interfaces. It encourages the use of Dependency Inversion and abstractions, similar to Clean Architecture. The application’s core remains unaffected by changes in external layers like UI, databases, or third-party libraries.
Clean Architecture: A Detailed Breakdown of the Fundamental Layers
Domain Model Layer — Similar to the “Entities” in Clean Architecture, the Core Entities in Onion Architecture represent the domain models that hold the core business logic and rules. They reside at the center of the “onion.”.
Domain Services Layer — This layer contains interfaces that define operations that can be performed on the domain models. These services are domain-specific and form the primary API for interactions with the core business logic.
Application Services Layer — This layer houses the application’s use cases and orchestrates the flow of data between the outer layers and the domain services. It acts as a translator for the core business logic to interact with external elements like databases and UI.
Infrastructure Layer — The outermost layer consists of all the technologies that interact with the application. This includes web servers, databases, libraries, and external services.
Managing Dependencies
In Onion Architecture, dependencies point inward, towards the Data Models. Each outer layer can depend only on the layers inside it. Dependency Inversion is used to invert the flow of dependency by having inner layers define interfaces that outer layers implement.
Advantages:
- Focus on Business Logic: Puts business logic at the core, making it easier for new developers to understand the purpose and functionality of the application.
- Testability: Easier to write unit tests for the core logic, and also for application services.
- Maintainability: Changing external interfaces or services won’t affect the application’s core logic
- Flexibility: Easy to replace external services, databases, and libraries.
Disadvantages:
- Complexity: May introduce an initial complexity for simple projects, similar to Clean Architecture and Hexagonal Architecture.
- High Initial Cost: Takes more time to set up the initial architecture.
- Over Abstraction: Just as with Hexagonal Architecture, over abstraction can lead to complications if not implemented judiciously.
Final Check
Although Onion Architecture, Hexagonal Architecture , and Clean Architecture share many similarities, they also have distinct differences that set them apart. Here is a comparative summary:
Focus and Objectives:
- Onion Architecture: The primary focus is on placing the core business logic at the center and having all other layers oriented toward this core.
- Hexagonal Architecture: The focus here is primarily on organizing the interactions between the application and the outside world. External systems (like UI, test harnesses, third-party services) connect to the main application through ‘ports’.
- Clean Architecture: The focus is on a clear separation of business rules from other concerns of the application. Each layer should only depend on the next layer through a well-defined API.
Layers:
- Onion Architecture: Layers (Domain Models, Domain Services, Application Services, External Interfaces) are organized in an ‘onion’ shape, and all external layers depend inwardly on internal layers.
- Hexagonal Architecture: The application is divided into an inside and outside. External agents connect to the internal application through ‘ports’ and ‘adapters’.
- Clean Architecture: Layers (Entities, Use Cases, Interface/Adapters, Frameworks and Drivers) are organized in four main parts, and each layer depends on the next layer in a well-defined manner.
Dependency Management:
- Onion Architecture: Dependencies always point inward.
- Hexagonal Architecture: Dependencies are managed between the inside and the outside through ‘ports’ and ‘adapters,’ but they usually also point inward.
- Clean Architecture: Dependencies are managed using the Dependency Inversion Principle and always point inward.
DDD Compatibility:
- Onion Architecture: Offers a structure that is compatible with DDD and directly supports DDD concepts like Bounded Contexts, Aggregates, and Value Objects.
- Hexagonal Architecture: Can be compatible with DDD principles but doesn’t offer as stringent rules about this as Onion does.
- Clean Architecture: Can be DDD-compatible but the primary goal of this architecture is not DDD; it is the separation of layers.
Each of these architectural approaches serves similar purposes but may be more or less suitable depending on the specific needs of your project
As a Result
The world of software development, with its constantly changing requirements and technological advancements, is in a continuous search for more effective and flexible architectural solutions. As a result of this search, modern software architectures such as Hexagonal, Clean, and Onion have emerged. These architectures are designed to simplify the development process, enhance the maintainability and testability of the code, and support the evolution of the application. In this article, we will delve into the advantages of these three architectures in detail, explore their similarities and differences, and examine which problem set each is most suitable for. Hexagonal, Clean, and Onion architectures offer unique and innovative strategies for managing the complexity of software and enhancing its functionality. Understanding and implementing these architectures can help software development teams create more effective, flexible, and sustainable solutions. Understanding the differences and similarities between these architectures will assist us in determining the best use cases for each.
Thanks for Reading…