Routes and Controllers in Express.js

Aprende a estructurar tus aplicaciones Express.js para escalabilidad y mantenibilidad separando rutas y controladores.

🌐

Let's build an app with Express! We start with an incoming request.

/* A wild request appears! */

Understanding Routes

In Express.js, a route defines how the application responds to a client request to a specific endpoint, which consists of a URI (or path) and a specific HTTP request method (GET, POST, etc.). Routes are the entry points to your application's backend.

Introduction to Controllers

A controller is a function that contains the business logic for a specific route. Instead of writing all the logic within the route definition, you separate it into a controller function. This makes your code cleaner, more organized, and easier to test and maintain.

Separation of Concerns

The Separation of Concerns (SoC) principle is key in software development. By separating routes (which handle the "what" - the endpoint) from controllers (which handle the "how" - the logic), you create a modular and scalable application structure. This is a cornerstone of the MVC (Model-View-Controller) pattern.

The Role of Middleware

Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. They can execute code, make changes to the request and response objects, end the request-response cycle, and call the next middleware in the stack. They are often used for tasks like authentication, logging, and parsing request bodies.

Practice Zone


Interactive Test 1: Match Concepts

Drag the descriptions to their correct Express.js concept.

Drag in the corresponding order.


Drag the options:

Define the endpoints for client requests
Handle the business logic for a route
Improves code maintainability

Completa el código:

Routes______
Controllers______
Separation of Concerns______
Unlock with Premium

Interactive Test 2: Code Structure

Rellena los huecos en cada casilla.


// app.js
const express = require('express');
const app = express();
const userRoutes = require('./routes/user_routes');

app.use(express.json());
app.use('/api/users', );

const PORT = 3000;
app.listen(PORT, () => console.log(`Server on port ${PORT}`));

// routes/user_routes.js
const router = express.Router();
const userController = require('../controllers/user_controller');

router.get('/', userController.);
router.post('/', userController.);

module.exports = router;

// controllers/user_controller.js
exports.getAllUsers = (req, res) => {
  res.status(200).json({ message: 'Get all users' });
};

exports. = (req, res) => {
  res.status(201).json({ message: 'User created' });
};
Unlock with Premium

Practical Example: Product Router

Create a simple Express application with a router for products. Define routes to get and create products.

* Write the code below. Correct characters will be shown in green and incorrect ones in red.

// routes/productRoutes.js const express = require('express'); const router = express.Router(); // Controller logic directly in the route file (for simplicity) const getProducts = (req, res) => { res.json({ message: "List of products" }); }; const createProduct = (req, res) => { res.status(201).json({ message: "Product created" }); }; router.get('/products', getProducts); router.post('/products', createProduct); module.exports = router; // app.js const app = express(); const productRoutes = require('./routes/productRoutes.js'); app.use('/api', productRoutes); app.listen(3000, () => { console.log('Server is running on port 3000'); });
Unlock with Premium

Knowledge Check

What is the main advantage of separating routes from controllers?


Unlock with Premium

From Theory to Production

Structuring your Express app with routes and controllers is a best practice. Here’s how it pays off in a real project.


1. Scalability and Teamwork

As your project grows, you'll have dozens of routes. Separating them into different files (e.g., `userRoutes.js`, `productRoutes.js`) and having corresponding controllers makes the codebase manageable. Different developers can work on different features without causing conflicts.

2. Advanced: Service Layer

For even more complex applications, many developers add a "Service Layer". The controller's job is just to handle the HTTP request and response. The service layer handles the complex business logic (e.g., calling multiple database models, integrating with external APIs). This further separates concerns.

// Controller
exports.createUser = async (req, res) => {
  const user = await UserService.create(req.body);
  res.status(201).json(user);
};

Practical takeaway: Always start your Express projects by separating routes and controllers. It sets you up for a clean, scalable, and maintainable codebase from day one.

Express.js Glossary

Router
An object that allows you to group route handlers for a particular part of your site.
Controller
A function that contains the business logic to be executed when a route is triggered.
Middleware
Functions that have access to the request (req) and response (res) objects, and the next function in the request-response cycle.
req (Request)
An object containing information about the HTTP request that raised the event.
res (Response)
An object used to send back the desired HTTP response.