Fast, unopinionated, minimalist web framework for Node.js
Álvaro José Agámez Licha
Senior Software Engineer
Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It's essentially a layer built on top of Node.js that makes server-side development much easier.
Start a new Node.js project and install Express with the following commands:
npm init -y
npm pkg set type="module"
npm i express
Routing in Express defines how the server responds to client requests on a specific path and method (GET, POST, etc.).
We can define as many routes as our API needs, and although we have complete freedom in how we name our routes, there are some best practices that are important to keep in mind.
Routing refers to how an application responds to a client request to a particular endpoint (URI) with a specific HTTP request method (GET, POST, etc.).
app.METHOD(PATH, HANDLER)
// User routes
router.get('/users', userController.getAll);
router.post('/users', userController.create);
router.get('/users/:userId', userController.getById);
router.put('/users/:userId', userController.update);
router.delete('/users/:userId', userController.delete);
// Nested routes
router.get('/users/:userId/orders', orderController.getUserOrders);
router.post('/users/:userId/orders', orderController.createUserOrder);
// Special actions
router.post('/users/:userId/activate', userController.activate);
router.post('/users/:userId/deactivate', userController.deactivate);
// Filtering examples
router.get('/products', productController.getAll);
router.get('/products?category=:category', productController.getByCategory);
app.use() is used to mount middleware functions. These functions have access to the request object (req), the response object (res), and the next middleware function in the application's request-response cycle.
app.use((req, res, next) => {
console.log('Time:', Date.now());
next(); // Pass control to the next middleware
});
Handles GET requests to a specific path for fetching resources.
app.get('/', (req, res) => {
res.send('Hello World!');
});
Route parameters are named URL segments used to capture values at specific positions in the URL.
app.get('/users/:userId', (req, res) => {
res.send(`User ID: ${req.params.userId}`);
});
Example request: GET /users/42
Response: User ID: 42
Query parameters are key-value pairs that appear after the ? in a URL.
app.get('/users', (req, res) => {
const limit = req.query.limit ?? 10;
res.send(`Showing ${limit} users`);
});
Example request: GET /users?limit=5
Response: Showing 5 users
Express matches routes in the order they are defined. The first matching route will handle the request.
Important rules:
// This will match /users/new AND /users/:id if placed first
app.get('/users/:id', (req, res) => {
res.send(`User ID: ${req.params.id}`);
});
// This needs to come first to be matched properly
app.get('/users/new', (req, res) => {
res.send('New user form');
});
// Correct order:
app.get('/users/new', (req, res) => {
res.send('New user form');
});
app.get('/users/:id', (req, res) => {
res.send(`User ID: ${req.params.id}`);
});
Understanding the flow of execution is crucial. Let's add logging:
app.use((req, res, next) => {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
next();
});
app.get('/debug', (req, res, next) => {
console.log('Middleware before response');
next();
}, (req, res) => {
console.log('Sending response');
res.send('Debug route');
console.log('Response sent');
});