1️⃣ Setup & Basic Server
// Import Express
const express = require('express');
const app = express();
const PORT = 3000;
// Basic middleware
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
// Basic route
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Start server
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
// Start server with error handling
const server = app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
server.on('error', (error) => {
if (error.code === 'EADDRINUSE') {
console.error(`Port ${PORT} is already in use`);
}
console.error('Server error:', error);
});
2️⃣ Routing Methods
// GET - Retrieve data
app.get('/users', (req, res) => {
res.json({ message: 'Get all users' });
});
// POST - Create new resource
app.post('/users', (req, res) => {
res.status(201).json({ message: 'User created' });
});
// PUT - Update entire resource
app.put('/users/:id', (req, res) => {
res.json({ message: 'User updated' });
});
// PATCH - Update partial resource
app.patch('/users/:id', (req, res) => {
res.json({ message: 'User partially updated' });
});
// DELETE - Remove resource
app.delete('/users/:id', (req, res) => {
res.json({ message: 'User deleted' });
});
// HEAD - Get headers only (no body)
app.head('/users', (req, res) => {
res.status(200).end();
});
// OPTIONS - CORS preflight
app.options('/users', (req, res) => {
res.setHeader('Allow', 'GET, POST, PUT, DELETE');
res.status(204).end();
});
3️⃣ Route Parameters & Query Strings
// Route parameters (:id, :name, etc.)
app.get('/users/:id', (req, res) => {
console.log(req.params.id); // e.g., "123"
res.send(`User ID: ${req.params.id}`);
});
// Multiple parameters
app.get('/users/:userId/posts/:postId', (req, res) => {
console.log(req.params.userId); // "123"
console.log(req.params.postId); // "456"
});
// Query strings (?key=value)
app.get('/search', (req, res) => {
console.log(req.query.q); // e.g., "nodejs"
console.log(req.query.page); // e.g., "2"
console.log(req.query.limit); // e.g., "10"
// All query params as object
console.log(req.query);
// { q: 'nodejs', page: '2', limit: '10' }
});
// Combined example
app.get('/users/:id/posts', (req, res) => {
const userId = req.params.id;
const page = req.query.page || 1;
const limit = req.query.limit || 10;
res.json({ userId, page, limit });
});
4️⃣ Request Object (req) Properties
app.get('/demo', (req, res) => {
// Request info
console.log(req.method); // "GET", "POST", etc.
console.log(req.url); // "/demo?test=1"
console.log(req.originalUrl); // Original URL before routing
console.log(req.path); // "/demo"
console.log(req.protocol); // "http" or "https"
console.log(req.hostname); // "localhost"
console.log(req.ip); // Client IP address
// Headers
console.log(req.headers); // All headers
console.log(req.get('user-agent')); // Specific header
// Body (requires middleware)
console.log(req.body); // Parsed request body
// Cookies (requires cookie-parser middleware)
console.log(req.cookies); // All cookies
// Files (requires multer middleware)
console.log(req.file); // Single file
console.log(req.files); // Multiple files
res.send('Check console');
});
5️⃣ Response Object (res) Methods
app.get('/response-demo', (req, res) => {
// Send data
res.send('Hello'); // Auto Content-Type
res.send({ message: 'JSON' }); // Auto JSON
res.send('<h1>HTML</h1>'); // Auto HTML
// Send JSON
res.json({ success: true }); // Sets Content-Type: application/json
res.status(201).json({ id: 1 }); // With status code
// Send status only
res.sendStatus(200); // "OK"
res.sendStatus(404); // "Not Found"
// Redirect
res.redirect('/new-path');
res.redirect(301, 'https://example.com'); // With status code
// Download file
res.download('./file.pdf');
res.download('./file.pdf', 'custom-name.pdf');
// Set headers
res.set('Content-Type', 'text/plain');
res.set({
'Cache-Control': 'no-cache',
'X-Custom-Header': 'value'
});
// Set cookie
res.cookie('name', 'value', {
maxAge: 900000, // 15 minutes
httpOnly: true, // Not accessible via JavaScript
secure: true, // HTTPS only
sameSite: 'strict'
});
// Clear cookie
res.clearCookie('name');
// End response
res.end(); // End without sending data
res.end('Done'); // End with data
// Render template (requires view engine)
res.render('index', { title: 'Home' });
});
6️⃣ Middleware
// Custom middleware (logging)
const logger = (req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
next(); // Pass to next middleware
};
app.use(logger);
// Middleware with path
app.use('/api', logger); // Only for /api routes
// Multiple middleware
app.use(express.json(), logger);
// Route-specific middleware
app.get('/protected', authMiddleware, (req, res) => {
res.send('Protected content');
});
// Error-handling middleware (4 parameters)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something broke!' });
});
// 404 handler (must be last)
app.use((req, res) => {
res.status(404).json({ error: 'Not found' });
});
7️⃣ Router (Modular Routes)
// Create router
const userRouter = express.Router();
// Middleware specific to this router
userRouter.use((req, res, next) => {
console.log('Time: ', Date.now());
next();
});
// Routes
userRouter.get('/', (req, res) => {
res.send('Get all users');
});
userRouter.get('/:id', (req, res) => {
res.send(`Get user ${req.params.id}`);
});
userRouter.post('/', (req, res) => {
res.status(201).send('Create user');
});
// Mount router
app.use('/users', userRouter);
// Access: GET /users, GET /users/123, POST /users
8️⃣ Error Handling
// Async error wrapper
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
// Usage
app.get('/async', asyncHandler(async (req, res) => {
const data = await someAsyncFunction();
res.json(data);
}));
// Custom error class
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
}
}
// Throw custom error
app.get('/error', (req, res, next) => {
next(new AppError('Resource not found', 404));
});
// Global error handler
app.use((err, req, res, next) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
res.status(err.statusCode).json({
status: err.status,
message: err.message
});
});
9️⃣ Static Files
// Serve static files from 'public' folder
app.use(express.static('public'));
// Serve from multiple folders
app.use(express.static('public'));
app.use(express.static('uploads'));
// Serve with virtual path prefix
app.use('/static', express.static('public'));
// Access: http://localhost:3000/static/image.jpg
// Custom options
app.use(express.static('public', {
maxAge: '1d', // Cache for 1 day
etag: true, // Enable ETag headers
lastModified: true // Enable Last-Modified header
}));
🔟 Template Engines
// Set view engine
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Render template
app.get('/', (req, res) => {
res.render('index', {
title: 'Home Page',
user: { name: 'John' }
});
});
// Common template engines:
// - EJS: npm install ejs
// - Pug: npm install pug
// - Handlebars: npm install express-handlebars
1️⃣1️⃣ Security Best Practices
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
// Security headers
app.use(helmet());
// CORS
app.use(cors({
origin: 'https://yourdomain.com',
credentials: true
}));
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP'
});
app.use('/api', limiter);
// Body parser limits
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Prevent parameter pollution
app.use((req, res, next) => {
req.query = cleanDeep(req.query);
req.body = cleanDeep(req.body);
next();
});
1️⃣2️⃣ Environment Variables
require('dotenv').config();
const PORT = process.env.PORT || 3000;
const MONGODB_URI = process.env.MONGODB_URI;
const NODE_ENV = process.env.NODE_ENV || 'development';
app.listen(PORT, () => {
console.log(`Running in ${NODE_ENV} mode on port ${PORT}`);
});
1️⃣3️⃣ Common Patterns
// Request validation middleware
const validate = (schema) => (req, res, next) => {
const { error } = schema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
next();
};
// Usage
app.post('/users', validate(userSchema), (req, res) => {
// Process validated data
});
// Pagination middleware
const paginate = (req, res, next) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const skip = (page - 1) * limit;
req.pagination = { page, limit, skip };
next();
};
// Usage
app.get('/items', paginate, async (req, res) => {
const items = await Item.find().skip(req.pagination.skip).limit(req.pagination.limit);
res.json(items);
});
💾 Save this cheat sheet! This covers 95% of Express.js use cases you'll encounter.
Top comments (0)