Clean architecture - making Node.js API shine!
Michael Kibenko · Follow
Published in ITNEXT
5 min read · Sep 6, 2021
Listen Share
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?
Open in app Sign up Sign In
Search Medium
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.
700 5
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.
Using Typescript will boost your architectural skills, you from doing
architectural mistakes by providing type safety, code readability, modularity,
encapsulation, code maintainability, and a better developer experience. Use
Typescript!
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! :)
Clean Architecture Mongodb Nodejs Software Development API
Follow
Written by Michael Kibenko
126 Followers · Writer for ITNEXT
Code sailor, creative decision-maker, tech lecturer. See you on linkedin.com/in/michael-kibenko-41403413a
More from Michael Kibenko and ITNEXT
Monolith vs Microservices vs Serverless and what to choose for your business needs
Michael Kibenko in NI Tech Blog
Monolith vs Microservices vs Serverless and what to choose for your
business needs
Every tech company with any sizes sometimes wonders about how to build their server-side
architecture and what approach to choose. Let's…
5 min read · May 22, 2020
56 1
Juntao Qiu in ITNEXT
Why Web UI Development Is So Hard?
Web UI development might appear straightforward at first glance, but delve deeper and you’ll
discover a multitude of complexities that…
8 min read · Sep 11
1.1K 13
Ok, Astro is the best web framework in 2023, here’s why
Futari Boy - developer & indie hacker in ITNEXT
Ok, Astro is the best web framework in 2023, here’s why
Discover why Astro is the best web framework in 2023 through a detailed explantion.
4 min read · Sep 9
583 8
Our experience using Storybook for React app
Michael Kibenko in NI Tech Blog
Our experience using Storybook for React app
Recently, our team started using React Storybook. In this post, I’ll share why we made this
decision, how we did it, what challenges we…
4 min read · May 5, 2021
45 1
See all from Michael Kibenko
See all from ITNEXT
Recommended from Medium
Domain-Driven Design (DDD) with Node.js: Organizing Your Application
Alessandro Traversi
Domain-Driven Design (DDD) with Node.js: Organizing Your Application
Domain-Driven Design (DDD) is a software development approach that emphasizes the
importance of understanding and modeling the domain of a…
3 min read · Jun 15
6
Dmitry Kruglov in Better Programming
The Architecture of a Modern Startup
Hype wave, pragmatic evidence vs the need to move fast
16 min read · Nov 7, 2022
6.1K 57
Lists
General Coding Knowledge
20 stories · 389 saves
Coding & Development
11 stories · 197 saves
Stories to Help You Grow as a Software Developer
19 stories · 417 saves
It's never too late or early to start something
15 stories · 141 saves
Samra Khan
Flutter — Clean Architecture
Clean Architecture is a software design principle that promotes the separation of concerns and
aims to create a modular, scalable, and…
5 min read · Jun 21
71 1
Vijini Mallawaarachchi in Towards Data Science
10 Common Software Architectural Patterns in a nutshell
Ever wondered how large enterprise scale systems are designed? Before major software
development starts, we have to choose a suitable…
· 5 min read · Sep 4, 2017
39K 127
Sudharsanan Rajaram
Swagger for Node JS API
Generating a Documentation in Node JS API is quite simple and it has become an essential task
for maintaining and scaling up any project…
2 min read · Jul 4
Difference Between Promise and Async/Await
Jeswanth Reddy in Version 1
Difference Between Promise and Async/Await
If you’re reading this, you probably understand how the promise and async/await are different in
the execution context.
2 min read · May 12
1.8K 15
See more recommendations