Express.js
Express.js cheat sheet with routing, middleware, request handling, error handling, and REST API patterns with Node.js code examples.
Other Node.js Sheets
Setup & Basics
Initialize and configure Express applications
Create and configure Express app
// Install
npm install express
// Basic setup
const express = require('express')
const app = express()
const PORT = process.env.PORT || 3000
// Middleware
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(express.static('public'))
// Start server
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
// ES6 modules
import express from 'express'Routing
Define routes and handle HTTP methods
Define and organize routes
// Basic routes
app.get('/', (req, res) => {
res.send('Hello World')
})
app.post('/users', (req, res) => {
res.json({ user: req.body })
})
// Route parameters
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id })
})
// Query parameters
app.get('/search', (req, res) => {
res.json({ query: req.query.q })
})
// Router
const router = express.Router()
router.get('/', handler)
router.post('/', handler)
app.use('/api', router)
// Route patterns (Express 5: string char-patterns removed - use arrays or RegExp)
app.get(['/abcd', '/acd'], handler) // was '/ab?cd'
app.get(/^\/ab+cd$/, handler) // was '/ab+cd' (abcd, abbcd)
app.get(/^\/ab.*cd$/, handler) // was '/ab*cd' (abcd, abxcd)
app.get(/.*fly$/, handler) // butterfly, dragonfly (RegExp still works)Middleware
Process requests with middleware functions
Create and use middleware
// Basic middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`)
next()
})
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})
// Route-specific middleware
app.get('/protected', authenticate, (req, res) => {
res.json({ data: 'secret' })
})
// Third-party middleware
const cors = require('cors')
const helmet = require('helmet')
const morgan = require('morgan')
app.use(cors())
app.use(helmet())
app.use(morgan('combined'))Request & Response
Handle request data and send responses
Work with req and res objects
// Request properties
req.params // Route parameters
req.query // Query string
req.body // Request body
req.headers // Headers
req.cookies // Cookies
req.method // HTTP method
req.url // URL path
req.ip // Client IP
// Response methods
res.send('text')
res.json({ data })
res.status(404).send('Not found')
res.redirect('/login')
res.render('template', { data })
res.sendFile('/path/to/file')
res.download('/path/to/file')
// Headers
res.set('Content-Type', 'application/json')
res.cookie('token', value, { httpOnly: true })Database Integration
Connect and work with databases
Integrate databases with Express
// MongoDB with Mongoose
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/myapp')
const User = mongoose.model('User', {
name: String,
email: String
})
app.get('/users', async (req, res) => {
const users = await User.find()
res.json(users)
})
// PostgreSQL with pg
const { Pool } = require('pg')
const pool = new Pool({
connectionString: process.env.DATABASE_URL
})
app.get('/users', async (req, res) => {
const result = await pool.query('SELECT * FROM users')
res.json(result.rows)
})Authentication & Security
Secure Express applications
Authentication and security best practices
// JWT Authentication
const jwt = require('jsonwebtoken')
app.post('/login', async (req, res) => {
// Verify credentials
const token = jwt.sign(
{ userId: user.id },
process.env.JWT_SECRET,
{ expiresIn: '1d' }
)
res.json({ token })
})
// Security middleware
const helmet = require('helmet')
const rateLimit = require('express-rate-limit')
app.use(helmet())
app.use(rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
}))Error Handling
Catch and handle errors gracefully in your Express application
// Async route handler wrapper
const asyncHandler = fn => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
// Route with async handling
app.get('/users/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user);
}));
// Global error handler (must be last)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
message: err.message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
});
});CORS & Security
Enable Cross-Origin Resource Sharing for API access from browsers
const cors = require('cors');
// Allow all origins (development)
app.use(cors());
// Specific origin
app.use(cors({
origin: 'https://example.com'
}));
// Multiple origins
const corsOptions = {
origin: function (origin, callback) {
const allowedOrigins = ['https://example.com', 'https://app.example.com'];
if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true // Allow cookies
};
app.use(cors(corsOptions));Add security headers to protect against common vulnerabilities
const helmet = require('helmet');
// Use helmet for security headers
app.use(helmet());
// Rate limiting
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests
message: 'Too many requests'
});
app.use('/api/', limiter);
// Prevent NoSQL injection (Express 5: req.query is read-only, so
// express-mongo-sanitize throws - sanitize at the data layer instead,
// e.g. parameterized queries + a maintained sanitizer that skips req.query)Request Validation
Validate and sanitize user input to ensure data integrity
const { body, param, query, validationResult } = require('express-validator');
// Validation middleware
app.post('/users',
body('email').isEmail().normalizeEmail(),
body('name').isLength({ min: 2 }).trim().escape(),
body('age').isInt({ min: 0, max: 120 }),
body('password').isLength({ min: 8 }).matches(/\d/),
(req, res) => {
// Check validation results
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Process valid data
const { email, name, age, password } = req.body;
// Create user...
}
);Configuration
Manage configuration and secrets using environment variables
// Load environment variables
require('dotenv').config();
// Access variables
const PORT = process.env.PORT || 3000;
const DB_URL = process.env.DATABASE_URL;
const JWT_SECRET = process.env.JWT_SECRET;
// Check required variables
const requiredEnvVars = ['DATABASE_URL', 'JWT_SECRET'];
requiredEnvVars.forEach(varName => {
if (!process.env[varName]) {
console.error(`Missing required environment variable: ${varName}`);
process.exit(1);
}
});
// Start server
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
console.log(`Environment: ${process.env.NODE_ENV}`);
});