anthonator

anthonator

I’m curious to hear people’s opinions on implementing the Onion Architecture in an Elixir application.

Jeffrey Palermo, the originator of the Onion Architecture, states that it is “unashamedly biased toward object-oriented programming, and it puts objects before all others”. However, there has been some discussion on implementing the Onion Architecture in Functional Programming.

The diagram depicts the Onion Architecture. The main premise is that it controls coupling. 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. This architecture is unashamedly biased toward object-oriented programming, and it puts objects before all others.

Has anybody in the Elixir community implemented the Onion Architecture in Elixir or another functional language? Has anybody implemented the Onion Architecture in an OOP language? If you have, what are your thoughts on implementing this architecture?

Do you think this architecture could be useful to the Elixir community? Is using this architecture a bad idea? A good idea? A waste of time? Do Elixir apps tend to exhibit this architecture anyway?

I’m looking forward to hearing people’s thoughts!

Showing Posts 1 to 7

Crowdhailer

Crowdhailer

Creator of Raxx

This might be a slightly controversial point but I don’t think Elixir code needs to be very different from OO code. A user struct is not very different from an immutable user object. The domain core being functionally pure is I link a good idea because it makes units very easy to test.

By the time you step out to application services and infrastructure, your code will no longer be pure. However at this level a Elixir program will probably be coordinating multiple process and they encapsulate state so again many of the OO lessons are still relevant.

So in summary I think that the onion architecture in Elixir is a good idea.

DianaOlympos

DianaOlympos

I would say that my main problems with that architecture are that it is badly defined

  1. If it is about code and use dependency injection, then… it is deeply single threaded. Which… urgh
  2. if it is about higher level stuff… Why not but it is highly specific. Why even need something that complex that limits you that much ? And why talk about Objects or DI ?

All in all.. I still do not understand all these talks about architecture. Think about your system as a whole, build from there, rewrite regularly, decouple stuff and please make it works safely before diving in complex architecture.

StefanHoutzager

StefanHoutzager

I did not dive into the onion thing. My time is limited, and I just read that tip of mr. Kunikow: [Functional Programming] Domain Modeling Made Functional (Pragprog) (F#). The writer of that book is also a nice humoristic and clear presenter. I can recommend
https://www.youtube.com/watch?v=AG3KuqDbmhM on the subject of a comparison of oo and fp dependency injection (it comes a bit later in the presentation).

peerreynders

peerreynders

I thought that looked familiar as it’s basically Alistair Cockburn’s Hexagonal Architecture.

I’m not even sure why it claims that its “unashamedly biased toward object-oriented programming, and it puts objects before all others” because it basically just takes the general notion of “separation of concerns” and transforms that into pleasingly shaped boundaries - manifesting themselves as “objects” at the lowest level of granularity and bending a layered architecture into an out-in-out circular shape on the highest level of granularity.

And it also seems that somehow the Onion Architecture got associated with DDD (Domain-Driven Design with Onion Architecture). Which is interesting because I suspect that similar criticism (Jim Coplien — Symmetry in Design) can be levelled against it - it relies heavily on symmetry (and hierarchy) which may not be inherent in the problem domain which can ultimately lead to accidental complexity.

From that viewpoint Coplien’s DCI (Data, Context and Interaction) may actually be a more profitable place to pilfer ideas from. While he’s still an object-oriented guy, he eshews class-orientation and his “network of objects” seem reminiscent of communicating BEAM processes.

anthonator

anthonator OP

If someone were to implement this in Elixir it may not make sense to bring over all aspects from the original article. I agree that dependency injection is one of my least favorite aspects.

However, I am intrigued by the clear separation between domain, application, and infrastructure code. Most apps that I encounter in the wild are “database first” and place the infrastructure layer in the middle. This tends to set the stage for a “Traditional Layered Architecture” which leads to a hopeless amount of coupling.

A lot of this may be obvious to others but judging from the projects I’ve worked on it doesn’t seem obvious to a good number of smart people I’ve worked with.

Qqwy

Qqwy

TypeCheck Core Team

In the end, the reason that many applications in the wild are extremely tightly coupled is possibly because it takes a conscious effort to not introduce coupling.

That for some reason the term ‘model’ started becoming confounded (moving from ‘conceptual model’, also known as ‘business logic’, to take on the extra meaning: ‘database model’, resulting in programmers only being able to think about both concepts simultaneously) did not help in this regard, as this resulted in very tight coupling of the database with the application logic.

In your application, the main piece that should dictate how everything else works, should be your business domain logic: The abstract representation of the part of real world your application attempts to help with (to ‘model’).

What database you use is an implementation detail.
What user-interface the business logic can be manipulated through is an implementation detail.

Yes, there can be multiple different kinds of databases in a single application, or none at all. Yes, you might both have a web interface, a command-line interface and an Application Programming Interface.

These decisions do not have impact on your business logic, but the inverse is true: Your business logic strongly impacts in what ways it make sense to store certain pieces of data, and in what ways it makes sense to interact with it.


I believe that above realization is the core of all these different kinds of architecture ideas. Whether you call the result Domain Driven Design, Onion Architecture, Hexagonal Architecture, Data Context and Interaction, SOLID, etc. does not really matter. Their goals are the same: To decouple the multiple pieces of your application, making sure that your code remains structured (understandable, maintainable and adaptable) over time.

Rather, I have somewhat the feeling that all these different names steal the wind out of each other’s sails a little bit, making all of them less valuable as a result (in a way similar to this).

peerreynders

peerreynders

However, I am intrigued by the clear separation between domain, application, and infrastructure code.

I’m not against being organized (i.e. observing separation of concerns) - in fact most of the success stories are probably based on the fact that projects went from not managing boundaries and dependencies appropriately to starting to having to think about them - but that doesn’t give the onion architecture “special powers”.

Most apps that I encounter in the wild are “database first” and place the infrastructure layer in the middle.

To certain degree that is simply an matter of perspective - and typically there are multiple perspectives. The onion architecture’s primary claim to fame is the direction of the interfaces - something that can’t even be discerned in the primary graphic. The domain logic gets to dictate the interfaces and types and the infrastructure has to implement everything based on those constraints.

So for example in Java-land that would mean that none of the classes in Java.sql would be allowed in the domain code, even something as convenient as ResultSet because that would ultimately couple the domain logic with the notion of a relational database. From the perspective of the Dependency Inversion Principle this has always been the right thing to do:

  • High-level modules should not depend on low-level modules. Both should depend on abstractions.
  • Abstractions should not depend on details. Details should depend on abstractions.

By extension Ecto.Changeset has no business appearing anywhere in your domain logic because Ecto is ultimately only part of your infrastructure - not your domain. So according to DDD you would have to build a repository around Ecto’s repo and transform all inbound and outbound data to basic and domain datatypes - no leaking of changesets and schemas allowed.

it doesn’t seem obvious to a good number of smart people I’ve worked with.

Loose coupling adds effort upfront. So a lot of those “smart people” will accept tight coupling either of their own accord (laziness) or because of pressure by management to produce something (we need this yesterday).

— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 92995 915
New
caslu
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
GES233
I’m posting this in response to Jose’s recent tweet (Cr. link) : People are sleeping on Elixir for a coding harness: Hot-code swappi...
New
_mfierro
Hello, I wrote Stop My Hand, a Scattergories-like web application using Phoenix/LiveView as my learning project for Elixir (after readin...
New
marciol
It would be helpful to have a list of companies worldwide that hire engineers without prior experience in Elixir. Often, it can be quite ...
New
durvia
Anyone running long-lived stateful processes on BEAM? We’re building an AI agent runtime and would love to compare notes. We’re a small ...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews