Onion architecture compared to hexagonal

Previous answers make a fundamentally incorrect statement about Onion architecture. They assert "in Onion the UI and Data access are part of the same layer". The confusion might come from thinking all layers talk to everything above and below them.

In reality an Onion diagram is a poor representation of the Onion Architecture. The key takeaway is that the core domain layer is agnostic of any surrounding layers and the surrounding layers typically are also agnostic of each other. Usually this means that a UI talks to a Service which talks to Data and Domain layers. The UI doesn't directly interact with the other layers, and the layer interactions are abstracted by using Dependency Injection and Interface Segregation.

To my knowledge there aren't any architectural patterns that advise mixing Data Access and UI (some, such as Active Record, mix Business and Data Access). Seperately, there are technologies that produce code that avoids layers--rapid development tools often do this, but those are tools that favor speed to deployment over design and maintainability.

Onion, Hexagonal, and Ports and Adapters are in fact all different names for the same conceptual architecture.

Mark Seeman has a great post that helps clarify how the differences, if any, are marginal and semantic: Layers, Onions, Ports, Adapters: it's all the same


What are the differences between them if any?

Onion: There are layers, with the dependencies always pointing inwards, i.e., a layer can use any of the layers inside it. The inner layer is Domain Model and the outer is infrastructure, but the number of layers between may vary.

Hexagonal (it's an alternative name for the original name "Ports & Adapters"): There are no layers. You have the application, the ports, and the adapters. The ports belong to the application, they are the API/SPI of the application. Adapters are outside the application, and each one depends on a port of the application.

The confusion some people have is that when implementing the hexagonal architecture, most of the people don't physically put every adapter in an artifact, but they put all together into one artifact (like the infrastructure layer). And also they make depend on the adapters on the whole app, not just the port they use. So it would be an Onion in fact.

Implementing hexagonal right should separate adapters from each other, and every adapter should depend just on the port it uses/implements (depending on whether the port is a driver or driven).

Another difference is that Hexagonal says nothing about the structure of the inside of the hexagon (the application).

What are the benefits of using one over the other?

The benefit of hexagonal is that it is more modular, you have a clear separation of components, preventing the leaking of code between them. Onion, on the other hand, is more dangerous in that sense, as you can access for example the database directly from the UI (they both belong to the same layer).

The benefit of Onion is derived from the above. As hexagonal have a lot of artifacts, if the project is big, the build of the whole project should take a lot of time.

Why you would use it? When to use it?

The point of using either of them is that you focus on the real problem you are trying to solve, without using any technology or framework. The application is technology agnostic, and it is easy to migrate from a framework to another. Both of them are called "clean" architectures because of that. You have your application core free of framework code, annotations, etc.

So... Why use them?

Because you improve maintainability, testability, and you have clean code.

When to use them?

I should rather say when not to use them. If the app you are developing is not complex, for example, it's just a CRUD, maybe it doesn't deserve to use them.

Personally, I like "Ports and Adapters" over the others.

Hope my explanation helped.


Hexagonal Architecture, also know as the ports and adapters focuses around infrastructure concerns.

Onion architecture focuses around domain concerns.

Taking the example of the persistence layer, you would use an ORM in order to send and retrieve data from a data store. The ORM represents an infrastructure concern and should be placed outside domain concerns, this is called an adapter and can be later changed with another ORM. Inside your domani (Onion) you would define interfaces so that your domain would not be concerned with the infrastructure, these interfaces are called ports.