Express is the most popular Node.js web framework. It provides a robust set of features for building web applications and APIs quickly and easily.
What is Express? #
Express is a minimal and flexible Node.js web application framework that provides features for web and mobile applications. It’s the de facto standard server framework for Node.js.
Why Use Express? #
- Minimal and flexible - Unopinionated framework
- Robust routing - Powerful routing system
- Middleware support - Extensive middleware ecosystem
- Fast development - Simple API for rapid prototyping
- Large community - Thousands of packages and plugins
Installing Express #
# Create new project
mkdir my-app
cd my-app
npm init -y
# Install Express
npm install expressHello World Server #
const express = require('express');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});Run the server:
node app.jsBasic Routing #
HTTP Methods #
const express = require('express');
const app = express();
// GET request
app.get('/users', (req, res) => {
res.send('Get all users');
});
// POST request
app.post('/users', (req, res) => {
res.send('Create a user');
});
// PUT request
app.put('/users/:id', (req, res) => {
res.send(`Update user ${req.params.id}`);
});
// DELETE request
app.delete('/users/:id', (req, res) => {
res.send(`Delete user ${req.params.id}`);
});
// Handle all methods
app.all('/secret', (req, res) => {
res.send('Secret area');
});
app.listen(3000);Route Parameters #
// Single parameter
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`User ID: ${userId}`);
});
// Multiple parameters
app.get('/posts/:postId/comments/:commentId', (req, res) => {
const { postId, commentId } = req.params;
res.send(`Post: ${postId}, Comment: ${commentId}`);
});
// Optional parameters with regex
app.get('/users/:id(\\d+)', (req, res) => {
res.send(`User ID (numbers only): ${req.params.id}`);
});Query Parameters #
app.get('/search', (req, res) => {
const { q, page, limit } = req.query;
res.json({
query: q,
page: page || 1,
limit: limit || 10
});
});
// GET /search?q=express&page=2&limit=20
Middleware #
Middleware functions have access to request, response, and next function.
Application-Level Middleware #
// Logger middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next();
});
// Authentication middleware
app.use((req, res, next) => {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
next();
});Route-Specific Middleware #
const authenticate = (req, res, next) => {
const token = req.headers['authorization'];
if (token === 'valid-token') {
next();
} else {
res.status(403).json({ error: 'Invalid token' });
}
};
app.get('/protected', authenticate, (req, res) => {
res.json({ message: 'Protected data' });
});Built-in Middleware #
// 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'));Third-Party Middleware #
const cors = require('cors');
const morgan = require('morgan');
const helmet = require('helmet');
// Enable CORS
app.use(cors());
// HTTP request logger
app.use(morgan('dev'));
// Security headers
app.use(helmet());Request Object #
app.post('/example', (req, res) => {
// Request properties
console.log(req.body); // Request body (needs express.json())
console.log(req.params); // Route parameters
console.log(req.query); // Query string parameters
console.log(req.headers); // HTTP headers
console.log(req.method); // HTTP method
console.log(req.url); // Request URL
console.log(req.path); // Path part of URL
console.log(req.ip); // Client IP address
console.log(req.cookies); // Cookies (needs cookie-parser)
res.send('OK');
});Response Object #
app.get('/response-examples', (req, res) => {
// Send text
res.send('Hello World');
// Send JSON
res.json({ message: 'Success', data: [] });
// Set status code
res.status(404).send('Not Found');
// Send file
res.sendFile('/path/to/file.pdf');
// Download file
res.download('/path/to/file.pdf');
// Redirect
res.redirect('/new-location');
// Set headers
res.set('Content-Type', 'application/json');
res.send('{"message": "Hello"}');
// Chain methods
res.status(200).json({ success: true });
});Building a REST API #
const express = require('express');
const app = express();
app.use(express.json());
// In-memory data store
let users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
];
// 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);
});
// 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: users.length + 1,
name,
email
};
users.push(newUser);
res.status(201).json(newUser);
});
// UPDATE user
app.put('/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' });
}
const { name, email } = req.body;
if (name) user.name = name;
if (email) user.email = email;
res.json(user);
});
// DELETE user
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === parseInt(req.params.id));
if (index === -1) {
return res.status(404).json({ error: 'User not found' });
}
users.splice(index, 1);
res.status(204).send();
});
app.listen(3000);Router #
Organize routes using Express Router:
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('Get all users');
});
router.get('/:id', (req, res) => {
res.send(`Get user ${req.params.id}`);
});
router.post('/', (req, res) => {
res.send('Create user');
});
module.exports = router;
// app.js
const express = require('express');
const app = express();
const usersRouter = require('./routes/users');
app.use('/api/users', usersRouter);
app.listen(3000);Error Handling #
// Custom error handler
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
error: {
message: err.message,
status: err.status || 500
}
});
});
// 404 handler
app.use((req, res) => {
res.status(404).json({ error: 'Route not found' });
});
// Async error handling
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
app.get('/async-route', asyncHandler(async (req, res) => {
const data = await someAsyncOperation();
res.json(data);
}));Template Engines #
Using EJS #
npm install ejsconst express = require('express');
const app = express();
// Set view engine
app.set('view engine', 'ejs');
app.set('views', './views');
app.get('/', (req, res) => {
res.render('index', {
title: 'Home Page',
users: ['Alice', 'Bob', 'Charlie']
});
});
app.listen(3000);<!-- views/index.ejs -->
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
<ul>
<% users.forEach(user => { %>
<li><%= user %></li>
<% }); %>
</ul>
</body>
</html>Environment Variables #
npm install dotenv// .env file
PORT=3000
DATABASE_URL=mongodb://localhost:27017/myapp
JWT_SECRET=mysecretkey
// app.js
require('dotenv').config();
const PORT = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});File Uploads #
npm install multerconst express = require('express');
const multer = require('multer');
const app = express();
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, Date.now() + '-' + file.originalname);
}
});
const upload = multer({ storage });
app.post('/upload', upload.single('file'), (req, res) => {
res.json({
message: 'File uploaded successfully',
filename: req.file.filename
});
});
// Multiple files
app.post('/upload-multiple', upload.array('files', 5), (req, res) => {
res.json({
message: 'Files uploaded',
files: req.files.map(f => f.filename)
});
});
app.listen(3000);Database Integration #
MongoDB with Mongoose #
npm install mongooseconst express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json());
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Define schema
const userSchema = new mongoose.Schema({
name: String,
email: String,
createdAt: { type: Date, default: Date.now }
});
const User = mongoose.model('User', userSchema);
// Routes
app.get('/users', async (req, res) => {
const users = await User.find();
res.json(users);
});
app.post('/users', async (req, res) => {
const user = new User(req.body);
await user.save();
res.status(201).json(user);
});
app.listen(3000);CORS Configuration #
npm install corsconst express = require('express');
const cors = require('cors');
const app = express();
// Enable all CORS requests
app.use(cors());
// Configure CORS
app.use(cors({
origin: 'http://example.com',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
// Enable CORS for specific route
app.get('/api/data', cors(), (req, res) => {
res.json({ data: 'This route has CORS enabled' });
});
app.listen(3000);Best Practices #
- Use environment variables for configuration
- Organize routes with Express Router
- Use middleware for common functionality
- Handle errors properly with error middleware
- Validate input before processing
- Use async/await for cleaner async code
- Log requests for debugging
- Secure your app with helmet
- Use compression for responses
- Set appropriate status codes
Common Middleware Packages #
npm install helmet cors morgan compression cookie-parser express-validatorconst express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const morgan = require('morgan');
const compression = require('compression');
const cookieParser = require('cookie-parser');
const app = express();
app.use(helmet()); // Security headers
app.use(cors()); // Enable CORS
app.use(morgan('dev')); // Request logging
app.use(compression()); // Compress responses
app.use(express.json()); // Parse JSON
app.use(cookieParser()); // Parse cookies
app.listen(3000);Express makes building web applications and APIs straightforward. Master these fundamentals and you can build production-ready Node.js applications.