63

Is there any difference between them (onion | hexagonal), from my understanding they are just the same, they focus upon the domain which is at the core of the application and should be technology / framework agnostic.

What are the differences between them if any ?

Also I see no real advantage on using one over the other or even against an N-layered architecture, if done bad just following any of them won't make any difference

What are the benefits of using one over the other and why you would use it ? when to use it?

Thanks

5 Answers5

71

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.

proximab
  • 1,865
  • 1
  • 13
  • 18
choquero70
  • 4,470
  • 2
  • 28
  • 48
  • 36
    **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).**: This statement is not correct. – Amit Joshi Aug 29 '19 at 10:24
  • 14
    As @AmitJoshi menetioend, the statement that "**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)**" is not correct. The UI and DataBase should not exist in the same layer! The UI generally belongs to the **Application** Layer whereas the DB should be in the **Infrastructure** Layer. – Otman IGHOULASSEN Aug 30 '19 at 12:14
  • 1
    @AmitJoshi IMHO the statement I made isn't incorrect. Look at the diagram by Jeffrey Palermo https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1 . He draws UI and infraestructure (database access among other things) in the same layer, in a layer above the Application Layer (application services). So the UI doesnt belong to the application layer, the UI belongs to the layer above the application layer – choquero70 Aug 30 '19 at 20:26
  • 3
    @choquero70 I think saying UI and database are in the same layer is the same mistake as what you mentioned with hexagonal, where people put everything in one artifact. With onion architecture you have layers, but layers can be further split, and within layer the general rule is that, _horizontal dependencies aren't allowed_. – wasyl Sep 09 '19 at 06:17
  • 1
    @wasyl it's not me who says that UI and DB are in the same layer, it's onion architecture who says it. In a layered architecture, two components in the same layer can talk to each other. So, UI and DB could talk to each other. I guess that what you call horizontal dependency is a component of a layer using another component of the same layer. If so, I don't agree with you when you say "horizontal dependencies aren't allowed". Components of a layer can use components of the same layer – choquero70 Sep 10 '19 at 11:22
  • @choquero70 I tried to find some sources for my claim but haven't found any. On the other hand, nowhere have I read an explicit statement that dependencies between components/parts of the specific layer can talk to each other freely. I suppose what I said is more of a good practice, but I understand it might not be in the definition of onion architecture. Do you have any sources which back up "omponents in the same layer can talk to each other freely" claim, if there are any? – wasyl Sep 11 '19 at 15:07
  • 2
    @wasyl I'm not saying that onion arch advocates accessing the DB from the UI, I'm just saying that you could do it, because it's a layered arch and both are in the same layer. It's on developer's side not to do it, but architecture would allow to do it, since they are in the same layer, and nowhere in the onion arch pattern definition says that it is forbidden. Example source of layered arch: "Software Architecture Patterns" book, by Mark Richards, O'Reilly Media, Feb 2015. Chapter 1, Figure 1-4 , https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html – choquero70 Sep 11 '19 at 20:20
  • 2
    @choquero Onion Arch is an adaptation of PaA. You have a vertical and horizontal separation. Vertical being a layering where outer units depend on inner units and inner units don't know anything about outer units. Horizontal separation in the outermost layer shown in the Palermo's diagram where you have APIs, infrastructure and all other implementation units don't know anything about each other either as they can only communicate via inner layers (mostly application layer). In .NET terms for ex., they would not be part of the same assembly nor would they have a direct reference to one another. – hcerim Nov 12 '20 at 22:23
  • Onion has nothing to do with P&A. Onion is just layers drawn as circles where each one depends on the inners, but it has no ports, no facets, that's why they are circles instead of polygons, and I don't remember in the onion definition they say that each layer is split into blocks that don't see each other. I think they say you have layers – choquero70 Nov 13 '20 at 00:35
  • Very nice answer, thank you! One thing: "When not the use them" is actually quite broad. E.g. you would rather use DDD in some areas with much business vocabulary. And I feel, you just focus on business applications and that's it, but there is much more software out there. You would probably use other mechanisms for games, e.g. just based on ECS. Microcontroller programming, drivers, and other low-level programming would also often not use such frameworks (although it would be nice). Clearly, many would profit from abstractions, but not necessarily onion or hexagonal. Then again, all similar:) – IceFire May 22 '21 at 08:08
  • You are right, it is supposed I'm talking about programming software that tries to solve business problems in isolation from real world devices. If I'm programming a driver for a device, let's say a printer, obviously I won't abstract away the low level relationship with the printer using ports and adapters, because the low level concepts are indeed the domain of my problem. – choquero70 May 26 '21 at 19:15
  • @choquero70 in the onion pic you shared https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1 there is a missing dividing line between UI and DB, but it is present in other diagrams of the onion architecture: https://dev.to/barrymcauley/onion-architecture-3fgl Palermo even affirms this in the article you shared, when he says: "In other words, all coupling is toward the center." So please revise the "access the DB directly from the UI" part. – Magne Oct 17 '21 at 22:51
  • @Magne the line between ui and db doesn't mind. Read my previous comments about components in the same layer in a layered architecture – choquero70 Oct 19 '21 at 05:57
  • 2
    @choquero70 I read them. But "Components of a layer can use components of the same layer" and "nowhere in the onion arch pattern definition says that it is forbidden" is factually wrong, since Palermo asserts that all coupling/dependencies are towards the center (i.e. towards more inner layers): "The fundamental rule is that all code can depend on layers more central, but code cannot depend on layers further out from the core. In other words, all coupling is toward the center." https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/ – Magne Oct 19 '21 at 13:13
  • 1
    @choquero70 Onion is different than a traditional layered architecture. Example: " The direction of coupling is toward the center. The big difference is that any outer layer can directly call any inner layer. With traditionally layered architecture, a layer can only call the layer directly beneath it. This is one of the key points that makes Onion Architecture different from traditional layered architecture." https://jeffreypalermo.com/2008/08/the-onion-architecture-part-3/ Also see the "Onion architecture (flattened)" diagram there, where no direct UI ←→ DB is allowed. – Magne Oct 19 '21 at 13:19
  • @wasyl, you are wrong, Onion arch is specifically stating that one shouldn’t access DB from UI; here I quote: “Based on the rules of the Onion Architecture, the SpeakerController … cannot use ConferenceRepository directly.” – Adrian Jun 29 '22 at 07:30
  • Awesome explanation! Helped me a lot, thank You – satma0745 Jun 02 '23 at 11:37
35

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

STW
  • 44,917
  • 17
  • 105
  • 161
  • 1
    IMHO the statement I made isnt incorrect. Look at the diagram by Jeffrey Palermo https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/ . He draws UI and infraestructure (database access among other things) in the same layer. And I wanna remark another thing: here https://jeffreypalermo.com/2008/08/the-onion-architecture-part-3/ he says that a given layer depends on any inner layers inside it, not just the layer bellow it. And I said the dependencies always point inwards, so a layer cannot talk to any layer outside it. I have no confussion about that – choquero70 May 11 '19 at 20:55
  • 1
    I read part 1 and part 3 and I don't think he's actually advocating mixing infrastructure code into a single module. Things like UI and Data Access are shown at the same level, but his writing and the "flattened onion diagram" hint that they're still separate layers / modules. – STW May 11 '19 at 22:16
  • 2
    he doesn't advocate mixing, but technically, since both are in the same layer, you could, although you shouldn't. It's on the programmer the decission of not mixing, but the architecture allows it. – choquero70 May 11 '19 at 22:26
  • 1
    They are at the same level, not the same layer, Just like there can be many application services not just one and Onion architecture is not clear about how they talk to each other, with the assumption that they don't need to. This is just to say that if Application service ever need to talk to external layers, it should be via dependency Injection, But doesn't mean you would need to talk. For example, UI layer can consume application services and never needed to be injected. But Db on the other hand needs to be injected. – Code Name Jack Mar 13 '22 at 07:45
  • However, in if we take Onion combined with MVC kind of use case, then we can inject the View as an interface into controller. – Code Name Jack Mar 13 '22 at 07:46
1

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.

0

There is a difference between the layered architecture and the onion related family of architectures. The layered architecture works with a hierarchical relationship between the user interface and the data access layers. In contrast, the onion architecture considers UI and data access to be part of the same layer.

How come user interface and data access are on the same layer? At the core of the onion architecture lies the domain with its business logic. This is the primary focus. The domain isn't above or below any other layer. It is the very center. User interfaces, rest endpoints and the like are secondary to the domain, just as data repositories.

The ports and adapters architecture (which is another name for the hexagonal architecture) makes this clear by its name: There are any number of ports that act as interfaces between the domain and the outside. Adapters implement the ports so that the ports can interact with the domain.


EDIT: I understand that the wording that "the onion architecture considers UI and data access to be part of the same layer" can be interpreted in a different way than was intended. The point is that in the onion architecture, the user interface and data access functionality are not in a hierarchical relationship, as is the case in the layered architecture.

Markus Pscheidt
  • 6,853
  • 5
  • 55
  • 76
-1

One of the differences is that in onion architecture you can access the database directly from the UI.

In hexagonal architecture, any UI access to the database must be through the Inbound port and follow the domain rules.

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 09 '21 at 09:30