Building Blocks:
Layered Architecture

Stop writing Spaghetti Code. Learn to organize your Node.js server into clean, testable layers: Controllers, Services, and Models.

Simulation ProgressStep 1 of 6
// The Request Life Cycle
// 1. Request -> 2. Controller -> 3. Service -> 4. Model -> 5. Database
0 EXP

Welcome to the backend. In Node.js, we avoid 'Spaghetti Code' by separating duties into layers: Controller, Service, and Model.

Controllers

Controllers are the Entry Point of your application logic. They sit right behind the Router. Their job is to understand the HTTP request (parse body, query params), perform basic validation, and then hand off the work to the Service layer.

Key Responsibility: HTTP Status codes and JSON responses. Controllers should never contain SQL queries or complex algorithms.

System Check

Which of the following belongs inside a Controller?

Server-Side Simulations

0 EXP

Log in to unlock these advanced training modules and test your skills.


Achievements

🏛️
The Architect

Successfully structure a request flow through all 3 layers.

✂️
Separation Master

Demonstrate understanding of Separation of Concerns.

🐞
Flow Debugger

Identify the correct layer for error handling.

Mission: Implement the Controller

The router has sent a request to you. Your job is to parse it and call the service. Write the code below.

A.D.A. Analysis:

> Logic valid. Separation of concerns achieved.

Challenge: Sort the Data Flow

Arrange the layers in the order a request travels, from receiving the request to saving data.

Service (Business Logic)
Controller (HTTP Handling)
Model (Database Schema)

Challenge: Complete the Service

Fill in the missing code to complete this Create User flow.

// Controller extracting data
const data = ;
// Service calling Model
const newUser = User.create(data);
return newUser.();

Architectural Consultant A.D.A.

Backend Dev Hub

Code Review

Submit your "Layered Architecture" project for a peer review on dependency injection patterns.

Mastering Separation of Concerns in Node.js

When building simple Node.js applications, it's tempting to write everything inside your routes (`app.get('/users', ...)`). This is often called the "Fat Controller" anti-pattern. As your application grows, this approach becomes unmaintainable. The solution? Layered Architecture.

The Three Pillars

By separating your code into three distinct layers, you create a system that is modular, easy to test, and easy to understand.

1. Controller

The entry point. Handles HTTP requests (req, res), validation, and sends responses. Rule: No business logic here.

2. Service

The brain. Contains business rules, calculations, and coordinates multiple models. Rule: No SQL queries or HTTP objects here.

3. Model

The data layer. Defines schema and interacts directly with the database (SQL/NoSQL). Rule: Just data access.

Dependency Injection (DI)

An advanced but critical concept in this architecture is Dependency Injection. Instead of requiring the Service inside the Controller directly (hard coupling), you pass the Service to the Controller.

This allows you to easily swap the real Service for a "Mock Service" when writing tests, ensuring your unit tests don't accidentally touch the real database.

Pro Tip: Always keep your controllers "skinny". If you see more than 10 lines of code in a controller method, you are likely leaking business logic that belongs in a service.

Node.js Architecture Glossary

Controller
Responsible for handling incoming requests and returning responses to the client. It orchestrates the flow of data.
Service Layer
Contains the core business logic. It sits between the Controller and the Model. It is agnostic of the transport layer (HTTP).
Data Access Layer (DAL)
Another name for the Model layer or Repository pattern layer. Logic dedicated strictly to database operations.
ORM (Object-Relational Mapping)
A library (like Sequelize or TypeORM) that converts data between incompatible type systems (Objects vs SQL tables).
Dependency Injection
A design pattern in which an object receives other objects that it depends on, decoupling the implementation.
Fat Controller
An anti-pattern where too much business logic is placed inside the controller, making it hard to test and maintain.

Credibility and Trust

About the Author

Author's Avatar

TodoTutorial Backend Team

Senior Node.js developers and architects dedicated to clean code standards.

This tutorial reflects enterprise-grade practices for scalability and maintainability in modern JavaScript environments.

Verification and Updates

Last reviewed: October 2025.

Checked for compatibility with Node.js 22 LTS and the latest Express.js security patches.

External Resources

Found an architectural flaw? Contact us!