Express
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.
- Handle routing (URL handling).
- Middleware chaining.
- Build REST APIs quickly.
- Easy integration with template engines.
What is Express?
Start a new Node.js project and install Express with the following commands:
What is Express?
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 in Express
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)
- app is an instance of express
- METHOD is an HTTP request method (GET, POST, etc.)
- PATH is a path on the server
- HANDLER is the function executed when the route is matched
Basic Routing Structure
- Use Nouns (Not Verbs) for Resources
- Use Plural Nouns for Collections
- Keep URLs Lowercase
- Use Hyphens for Multi-word Paths
- Nest Resources Properly
- Use Forward Slashes for Hierarchy
- Use Query Parameters for Filtering and Sorting
- Be Consistent
Routing Good Practices
Example Of Well-Structured Routes
// 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()
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()
app.get('/', (req, res) => {
res.send('Hello World!');
});
Route parameters are named URL segments used to capture values at specific positions in the URL.
Route Parameters
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.
Query Parameters
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:
- Specific routes should come before generic ones
- Error handlers and 404 routes should come last
Route Order Matters!
Route Order Matters!
// 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}`);
});
Logging And Debugging
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');
});
Logging And Debugging
- Use console.log to track execution flow
- Check the order of middleware registration
- Remember that res.send() ends the response
- Use tools like Postman to test routes
- Response is sent to client
- Use Node.js debugger (with VS Code)
Summary Of Execution Order
- Request comes in
- Matches middleware in registration order (app.use)
- Matches route handlers in registration order
- Executes all matching middleware/handlers until response is sent
- If no response is sent, falls through to 404 handler
- Response is sent to client
Coding Time

HyF Node.js Week 02
By Alvaro Agamez
HyF Node.js Week 02
- 65