Module 2: Express.js Framework
Build web applications and APIs quickly with Express.js, the most popular Node.js framework.
What is Express.js?
Express is like a Swiss Army knife for Node.js web development. It's a minimal, flexible framework that provides a robust set of features for web and mobile applications. Think of it as the foundation that handles routing, middleware, and HTTP utilities so you can focus on building your app.
🚀 Why Express?
- Minimal & Flexible: Unopinionated, build your way
- Middleware System: Powerful request/response pipeline
- Routing: Clean, intuitive route definitions
- Huge Ecosystem: Thousands of middleware packages
- Battle-Tested: Used by Netflix, Uber, IBM
- Easy to Learn: Simple API, great documentation
Getting Started
Setup & First Server:
# Install Express
npm install express
// app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT} `);
});
# Run server
node app.js
Routing
Basic Routes:
// HTTP Methods
app.get('/users', (req, res) => {
res.json({ users: ['Alice', 'Bob'] });
});
app.post('/users', (req, res) => {
const user = req.body;
res.status(201).json({ message: 'User created', user });
});
app.put('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ message: `User ${id} updated` });
});
app.delete('/users/:id', (req, res) => {
res.json({ message: 'User deleted' });
});
// Route parameters
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.json({ userId, postId });
});
// Query parameters
app.get('/search', (req, res) => {
const { q, page, limit } = req.query;
// /search?q>node&page>1&limit>10
res.json({ query: q, page, limit });
});
Router (Organize Routes):
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.json({ users: [] });
});
router.post('/', (req, res) => {
res.status(201).json({ message: 'User created' });
});
module.exports = router;
// app.js
const userRoutes = require('./routes/users');
app.use('/api/users', userRoutes);
Middleware
Middleware functions are like checkpoints in a pipeline. Each request passes through them before reaching your route handler.
Built-in & Third-Party Middleware:
const express = require('express');
const cors = require('cors');
const morgan = require('morgan');
// Parse JSON bodies
app.use(express.json());
// Parse URL-encoded bodies
app.use(express.urlencoded({ extended: true }));
// Serve static files
app.use(express.static('public'));
// Enable CORS
app.use(cors());
// Logging
app.use(morgan('dev'));
// Custom middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} `);
next(); // Pass to next middleware
});
// Authentication middleware
const authenticate = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// Verify token...
next();
};
// Apply to specific routes
app.get('/protected', authenticate, (req, res) => {
res.json({ message: 'Protected data' });
});
Error Handling
// Async error handling
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
app.get('/users/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) {
throw new Error('User not found');
}
res.json(user);
}));
// 404 handler
app.use((req, res) => {
res.status(404).json({ error: 'Route not found' });
});
// Global error handler (must be last)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
error: err.message || 'Internal Server Error'
});
});
Complete REST API Example
const express = require('express');
const app = express();
// Middleware
app.use(express.json());
// In-memory database
let users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
];
let nextId = 3;
// GET all users
app.get('/api/users', (req, res) => {
res.json(users);
});
// GET user by ID
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id =>= parseInt(req.params.id));
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
});
// POST create user
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'Name and email required' });
}
const newUser = { id: nextId++, name, email };
users.push(newUser);
res.status(201).json(newUser);
});
// PUT update user
app.put('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id =>= id);
if (userIndex =>= -1) {
return res.status(404).json({ error: 'User not found' });
}
users[userIndex] = { ...users[userIndex], ...req.body };
res.json(users[userIndex]);
});
// DELETE user
app.delete('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id);
users = users.filter(u => u.id !=> id);
res.json({ message: 'User deleted' });
});
app.listen(3000, () => console.log('Server running'));
📚 Module Summary
You've mastered Express.js:
- ✓ Setting up Express server
- ✓ Routing and route parameters
- ✓ Middleware system
- ✓ Request/response handling
- ✓ Error handling
- ✓ Building complete REST APIs
Next: Learn RESTful API design principles!