Everything you need to know about Clean Architectures

Back in 2012, Bob Martin coined the term “Clean Architecture” to refer to those software architectures that meet these requirements:
- They are independent of the framework
The architecture does not need a framework underneath to work, our code should be able to be ported to another framework and still work. This does not mean that our infrastructure code does not require changes. - They are testable
The business rules of our code should be testable (at least unitarily) without depending on web servers, databases, user interface or any third party libraries. - They are independent of the presentation layer (UI).
The presentation layer or frontend should be independent of the system, replaceable and multimedia, that is, it should be able to be a web environment, a console environment, a mobile app, another API or any other system we can imagine. - They are independent of the database (DB).
We should be able to switch from MySQL to PostgreSQL, MongoDB or any other provider without affecting our business rules. This does not mean that our infrastructure code does not require changes. - They are independent of any external dependence (third parties)
Everything is replaceable, no dependency should be strong. Not convinced by our UUIDs library? Replacing it should be trivial. Change ORM? The business logic should not notice.
The dependency rule
Let's look at a simplified version of the above scheme:

Each of the concentric circles represents a layer, and this layer in turn is a barrier that can only be crossed by its upper layers. Thus:
- Infrastructure you can access Application and to Domain
- Application you can access Domain
- Domain can only access Domain
The further inward we penetrate into the layers, the deeper we get into the business logic, rules and policies. The further out we move, the closer we are to external agents or mechanisms (web or mobile clients, external services or APIs, infrastructure services such as databases, queuing systems, etc).
Layer contents
Each one of these layers contains different elements of our code, we are going to make a small review to the content of each one of them:
Domain
This is the layer closest to the business, not to say that it is the business itself. The domain layer is where all the fundamental pieces reside, which will also serve as a common language to communicate between the other layers. For example:
- Entities: data models with their own identity, composed of Value Objects, which may or may not be anemic.
- Value Objects: fundamental pieces to model entities or aggregates. The value objects represent the basic elements of our domain, such as the id These tiny classes contain the validation logic of their values, they have no entity of their own and are compared by value, just like any other primitive.
- Services: are small classes that perform an action, such as retrieving a user from the database, constructing the entity and returning it, or returning a NullObject if it does not exist. These services can be used alone or combined in the different use cases.
- Events: Domain events are the most efficient way to communicate in the opposite direction of the dependency rule. If a domain action requires triggering another application layer use case, it will be in reaction to an event.
- Exceptions: classes that represent common errors that occur in our application. “User not found”, “Insufficient money”, “Value cannot be negative...”, etc.
- Contracts: By contracts, of course, we are referring to interfaces such as UserRepository, LogReporter, ExceptionTracker... etc. That is, contracts to be implemented in the infrastructure layer. For example: UserRepositoryMySQL, SumoLogicLogReporter o SentryExceptionTracker. These contracts will allow us to implement unit investment and give us the ability to change these dependencies, facilitating for example the transition from MySQL to MongoDB, since the interface (contract) will be the same (UserRepository), but the implementation does not (UserRepositoryMySQL → UserRepositoryMongo).
Application
In this layer will reside the use cases, that is to say, the orchestrators that, making use of domain elements such as entities, exceptions, services, value objects... combine them to obtain an answer.
Patterns such as CQS y CQRS or just simpler use cases.
Infrastructure
Here we have implementations of the different contracts defined by the domain. This is the layer whose code can vary the most when porting our project from one framework to another or when changing the database provider or when changing a library. third party on the other.
Example of an application flow
Let's see an example of the flow of a endpoint:

In this image we can appreciate some of the components involved in the execution of a endpoint, and I have associated each color with the color of the layer it belongs to.
- Controller: There can be discrepancies here and, in many cases, there are those who consider controllers as part of the application layer. Theoretically this is correct, but in practice we find many frameworks that prevent the controller from being a decoupled element, since it has to inherit from certain classes in order to function correctly, so in this example the controller will be part of the infrastructure layer and we will consider it as part of the framework.
Its mission in this case is simply to extract the data from the request, encapsulate the data in a DTO and pass it to the use case to handle. Once it receives the response, it will choose the appropriate presentation and return the response. - Use case: This is the part of our code that coordinates the execution of the business logic. It may include validations of input data and coordination of different domain services to obtain the desired response, as well as throwing exceptions if an error (expected or unexpected) occurs.
- Service. This is where the logic of our application lives, where the policies we have defined are executed and where all the knowledge resides.
As can be seen, domain services may require the use of infrastructure elements, but never in a direct way, since we make use of the unit investment to achieve it.
Known Clean Architectures implementations
Now that you know a little more about clean architectures, you might be curious and want to implement them in your projects. Where should you start?
First of all, it is recommended that you know and master some of the most popular implementations, so you can choose the one that best suits your style, your language or your way of thinking. Some of the most popular implementations are:
- Hexagonal Architecture. From Alistair Cockburn.
- Onion Architecture. From Jeffrey Palermo.
- Screaming Architecture. From Bob Martin.
- DCI. From James Coplien.
- ECB. From Ivar Jacobson.
You can look for more information about all these architectures and learn a little more about their principles and use cases, and don't forget to stay tuned to our blog, because we will discuss many of them in future posts.

