Why we use layered architectures
Tags: architecture, webdev, api, microservices
Published: 2022-07-25 16:45:00

I recently looked for articles that I could forward to explain why we use often choose a layered architecture when creating a new service. 

And I found none. The articles I found either did not try to explain the why or, in my opinion, missed the point by just stating that "this is easy". So, here is my attempt to explain the why of the layered architecture.

_Disclaimer_: I am not an architect. This is only my understanding as a software developer. If you see anything wrong or missing, please reach out, I will happily update the article (and my knowledge).
<br><br>
## What is a layered architecture

A layered architecture is a way to design a service by dividing its logic in layers. Each layer is only allowed to call the layer directly below.

We usually use these 3 layers:
1. The _API/UI_ layer: exposes the API or the UI and is responsible for authentication and requests handling.
2. The _business logic_ layer: everything that is business logic, data validation and processing.
3. The _data access_ layer: responsible for the interactions with the database.

It is usually represented like this:
![Layered architecture drawing (the layers on top of each other with arrows to the below layer)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2d7ynxhkpz2igevb4xl.jpg)
<br><br>
## Why we are using a layered architecture

There are many reasons why we may want to use a layered architecture. Even the reason "because I was told to" is valid.

The following reasons are the reasons that I think have the most valuable impact.
<br>
### It tends to remove surprises

The layers separation forces us to separate the logic in a given way. One of the consequences is that it make it easier to find what we are looking for. Everything is where it should be.

If we are looking for an API route, we know that it will be in the API layer. The same is true if we are looking for a specific request to the database, it will be in the data access layer.

It also make it easier to navigate in the code. We know that a request is starting at the API layer and we can drill down the layers if we want to know the implementation details.
<br>
### It helps reuse the logic

One of the direct results of the separation of the API logic, the business logic and the data access logic is that it is way easier to reuse the logic without duplicating it.

It is easier to reuse the business logic in multiple API routes because it is not mixed with a specific route logic. It is also easier to reuse the data access logic because it is not mixed with a specific business logic part.

For example, instead of duplicating the query to retrieve an entity everywhere, it can - and probably should - be a single function in the data access layer.

(Yes. It could and should be the case even without using the layered architecture. But we see things we can never unsee in this world.)
<br>
### It makes it easier to change

The consequence of separating the logic is that is it way easier to change any part of it.

For example, if we have a single function to retrieve an entity, we have only one place to change when the filter has to change.

We can also go a step further. It is way easier to replace a whole layer if we need it. (Even if we probably would never want to replace the business logic layer. It makes more sense for the other layers.)

For example, we can replace the data access layer with limited to no impact on the other layers. It may happen if we want to switch the database engine that we use.

To make this even easier, the layers should know each other only by interface and avoid exposing their implementation details. Dependency injection can help for that.
<br>
### Throwing big principles names

Since we love to name things, I thought I would try to throw big principle names that apply there:

- Because it gives a structure and define where things are expected to be, it contributes to the principle of least surprise.
- Because each layer has a well defined role, it contributes to the separation of concerns principle.
- Because it helps to avoid duplication of the logic, it contributes to the "don't repeat yourself" principle.
- To make it easier to change, we can use the inversion of control principle with dependency injection.


## Conclusion

We use the layered architecture because it is quite simple to implement and helps a lot to maintain a project.

It is of course possible to make a mess while implementing it. But the structure it gives guide us in the right direction.

If you see something wrong or something that I might have missed, please reach out. I would love to learn more. And I would like this article to be as complete as possible to be able to share it next time.

Hope it helped!