Hexagonal Architecture is very popular these days. However, I have seen that a lot of the resources out there that try to teach it do so in a very abstract and technical way. While that is great for understanding all the details, it makes for a poor introduction.
So, in this article, I would like to address this issue. I would like to make a simple and straightforward introduction to HA (Hexagonal Architecture) and give you some other resources for further learning, including a public repo that applies HA that I created for this article.
So let's begin!
What is Hexagonal Architecture?
Hexagonal Architecture is a design paradigm that focuses on separating the core of the application from everything else and specifying rules on how these two parts should interact.
What is the "core of the app"? What is "everything else"?
The core of the app is the business logic. All the things that make your app your app, no matter what external tools you use.
For example, if you are making a todo app, you want to be able to create todos, update todos, and remove todos. This is the core of the app.
Your app would still be a todo app if, instead of Postgres, you used SQLite; if instead of Prisma, you used Drizzle; or if instead of getting requests via a NestJS server, you used a CSV processor. These things that are not the core are "everything else".
According to HA, how should the "core of the app" interact with "everything else"?
By using ports.
Ports are the contracts that the core of the app establishes with "everything else" to work.
So, for example, if you want to create a todo, a port would specify that the core app needs a JSON object that provides a title and a description. It doesn't matter if this object comes from an HTTP request, a CSV file, or whatever. The app needs what the port specifies.
To follow this example, a tool like NestJS could get a POST request that a user sent and pass the relevant information following the port contract to the app.
Of course, in this example, we need something to get the request, manage the validation, and send it to the core app following the port contract. This is called the adapter. It's an adapter because it adapts the incoming information into something the core app can use.
To create a little diagram:
User sends request $\rightarrow$ NestJS controller gets it, validates it, and sends it to the core app by obeying a port contract (Adapter) $\rightarrow$ App processes the request (Core App)
The same process is followed for outgoing requests from the core app.
To put an example:
Imagine the core app, once it has received the correct data to create a todo, wants to store it in the database. The core app would send the correct information to the ORM/Database adapter by obeying a port contract, and the adapter would process the todo saving.
Notice that adapters not only adapt incoming information (driving side), they also adapt information from the app to the necessities of external services like an ORM (driven side).
Are there any other rules? That seems easy.
The core concept is not hard to grasp, but the implementation can get tricky.
For example, it is important to not mix the core of the app with the rest, which is easy to say but hard to do.
You do not want the business logic to depend on the ORM, for example. If you are using Prisma as your ORM and then decide to change it to Drizzle, you should not need to change the business logic. If you do, you have not implemented HA correctly.
Where can I learn more about HA?
I highly recommend these two articles to begin with. I think they offer a great explanation.
This one is a great follow-up reading. It is easy to read but gives more specific details about HA: Understanding Hexagonal Architecture - DEV Community
This other one is great because it gives a TS example of HA: A Detailed Guide to Hexagonal Architecture with Examples | by Dev Cookies | Medium
Is there any real-world example code I can check?
Yes! I have created a project that follows the patterns of HA as strictly as I could: Xalsar/user-posts-backend
Good bye! 👋
Hope you liked this little introduction to the topic. Feel free to ask questions or give feedback in the comments if you have it.
Cheers! And happy coding!
Top comments (0)