DEV Community

ChunTing Wu
ChunTing Wu

Posted on • Updated on

Layered Architecture Clarification

Layered architecture is a common pattern of an architecture design, and it is very suitable for a small scale monolith. There are many advantages such as,

  1. very easy to design and implement
  2. very in line with human nature
  3. cooperate with each other easily

When we are talking about the layered architecture, we often have a myth; in order to replace the dependency, we should make those dependencies as a layer.

In fact, that's not the purpose of layered architecture. I believe we seldom need to change a database, a framework, even a programming language. Therefore, what is the benefit of using layers?

Before we discuss further, we should see an example first.

Image description

The above diagram is a classic layered architecture for a web server. We separate a request flow into 4 components, route, controller, service and repository. Each component has its responsibility to handle a part of a request flow. This kind of implementation is also known as Single-Responsibility Principle.

In many articles, we had been taught that route is made for the web framework changed, and the repo is to nail the database. However, as I mentioned, we seldom need change those hard things. Route and repo here are just completing their own duties.

Single-Responsibility Principle

I will describe those 4 components' responsibilities to let you realize them more confidently.

  • Route is a the wrapper of a web framework. To interact with a framework and hide the implementation, we build a layer to enclose those details. In route layer, we usually define HTTP routes right here including HTTP methods and URI.
  • Controller is the first line to handle a request. The main responsibility is validating the input request and assemble the response. This layer often implement some error handlers to reflect like "400 Bad Request", "500 Internal Server Error", etc.
  • Service is where the business logic in. The core values of a web product are all here. If it is a E-commerce site, service will calculate the recommendation, orchestrate the render content, and all other logic.
  • Repo is an abstraction onto a database. In order to isolate the business logic, we don't want the database operation to pollute the code in services, thus, repo plays this role in accessing persisted data.

The text description is a bit abstract, so I provide a more concrete example: https://github.com/wirelessr/Clean-Architect-in-Golang

The GitHub repository is quite simple due to the screaming architecture, hence, we can know this is a classic web service.

  • Route is a mux wrapper in http. It will do nothing and route HTTP request to the controller.
  • Controller defines API interfaces. In AddPost, it also validates the request format and assembles the response.
  • Service own all business logic including how to access durable data, what the post format is, and how to generate the post identifier.
  • Repo hides all database details, so you can choose what data store you want. But, again, we don't change our data store decision easily. Therefore, repo here is to encapsulate the data store access to make service be independent from firestore.

What's Benefit

Do we just separate our web service into several layers for SRP? No. Actually, this comes some benefits. Let me show two most important advantages,

  1. Layers make testing become more easily.
  2. If those layers are modules, we can decouple the deployment of layer modules.

The second one is straightforward. Thus, I will dive into the test. According to my previous article, we can leverage the dependency injection to accomplish a high testing coverage. For instance, in my golang example, in order to verify the service, we can create a mocked repo to ignore the data store access.

Conclusion

There are many article trying to compare layered architecture and microservice architecture. However, layered architecture is not only an architecture pattern but also the coding technique for a SOLID software. This article tells you still can use layered architecture in your microservice like my post example. They are not two mutually exclusive things; moreover, they are more close to each other.

Discussion (2)

Collapse
amrelmohamady profile image
Amr Elmohamady

I would also add a validation layer before the controller to validate the request body. But I don't get why the repo layer when you are using an orm it just adds extra complexity, why not services just deal with the orm directly

Collapse
lazypro profile image
ChunTing Wu Author

For a simple application, it is feasible to use ORM instead of Repository. However, in an enterprise application, the domain object is not one-to-one mapping to a table or some rows. A domain object is composed of many data, and there are rich constraints between the data. This is also called Impedance Mismatch.

In order to solve the mismatch, we usually introduce a Repository between the domain layer and storage layer. Repository is not only responsible for accessing the data but also ensure the data constraints.