I first encountered the subject of Clean architecture when I worked as a native Android dev, where we spent a lot of time thinking about architecture and design patterns. When I transitioned to a JavaScript stack I noticed many production projects don’t devote much thought to the code architecture.
Want to make practice training about Clean architecture and Node.js?
You are invited to take a look at the course I’ve created, where you will write a complete system in Node.js based on Clean architecture principles, with my guidance.
Using Clean architecture for Node.js API Bootcamp
So, why should we think about code architecture?
Code scalability: Adding a new feature is challenging if you haven’t structured your code correctly — and you will find yourself breaking many SOLID principles in order to make the change.
Maintainability: Let’s assume that some of the system requirements changed, or you decided to change one of your frameworks or libraries. The transition can be straightforward when all of the system components are separated from each other, with fewer breaking changes.
Testability: We need to test our app using different types of tests, among them unit, integration, functional, smoke, and e2e tests. The separation of elements lends itself to easier testing, where we can test each module independently of others, with specific injected properties.
Readability: Developers have different opinions about code readability, but everyone will agree that readability increases when your code is separated along with single well-defined responsibilities.
Looking at the example below, found in many production projects, let’s analyze the problematic aspects of this code.
Code scalability: Assuming we want to add validation of the ID parameter before the Model execution, we will need to add the validation logic in the request handler, and this will break the single responsibility principle because the responsibility of the controller is to parse the request data and reply with a relevant result.
Solution: Call a service layer that is responsible for processing this request.
Maintainability: Assuming for some reason you decided to change your database layer to Azure Cosmos DB instead of Mongo DB, in this case besides many data migrations, you will need to change much of your codebase.
Solution: Prepare a parallel repository layer that will execute Cosmos DB instead of Mongo DB, and when it is prepared and tested just replace it with some dependency injection mechanism. This solution will allow you to safely test the solutions side-by-side in a production-like environment using some toggle mechanism.
Testability: In order to test this function, you will need to use some form of mock DB and make a fake request using something like chai-http. The problem here is that this test will be hard to initialize and it will take a long time to execute.
The second problem here is that you can’t test every part of this code independently.
Solution: This controller should call a service layer that will be responsible for processing the request. Once you’ve done that, testing should be easy: just make a mock service with your expected data responses and test the service logic independently — thus you’ve decoupled the business logic from the cumbersome to test fetching technology (in this case, HTTP).
So, how do we use Clean architecture in our code?
Clean architecture is a software design philosophy that advocates for the separation of layers of code. We will use the metaphorical concept of layers as rings, visualized in the image above, to examine this philosophy at a glance — for a basic Node.js API project.
Yellow layer: The Web server layer — including routes, will execute controllers.
Red layer: The Controllers layer, which will receive the users’ data and execute the relevant use cases and compile a structured response.
Green layer: The use cases layer, will receive the user data and will process this request including validation and external systems reporting (such as Kafka or Kibana), which will receive the data from the entity repository layer as a source of truth.
Blue layer: The entities layer, will include the entities and entities repositories — only this layer will make DB queries, and access other services or third parties to get data.
Code Dependency Rule: Code Dependencies can only move from the outer levels inward. Code on the inner layers can have no knowledge of functions on the outer layers. The variables, functions, and classes in the outer layers cannot be mentioned in the more inward levels.
Dependency injections: In order to be flexible with project dependencies, use any dependency injection mechanism that can inject your layers based on the specific configuration.
Response contracts: In order to make your API predictable, use the response contract layer, which means that every response should be structured, including errors.
If you want to see how to use the Response contract layer in practice, join my course on udemy.com
Using Clean architecture for Node.js API Bootcamp
Keep in mind — Clean architecture is a suggestion, not a rule!
Clean architecture can be hard and time-consuming for programmers to meet the philosophy for the first time, if you don’t have that time for your project just use a basic logical separation of concerns.
Controller will receive the user’s requests and reply with a structured response.
Service will process the user’s request, including validations and third-party reporting, and will receive data using the repository layer as a source of truth.
Repository will function as the application’s source of truth, will include the DB and external services queries.
“Your architectures should tell readers about the system, not about the frameworks you used in your system” — Robert C. Martin.
Conclusions
Good architecture is key to building modular, scalable, maintainable, and testable applications. One of the most popular architectures is Clean architecture, but every project may have specific needs. Just start to think about separation of concerns, and about how to not write your code as one big block, and you will get a good project that is not scary to maintain and easy to test.
Want to learn more?
You are invited to take a look at the course I’ve created, where you will write a complete system in Node.js based on Clean architecture principles, with my guidance
Using Clean architecture for Node.js API Bootcamp
Happy hacking! :)
所有评论(0)