DEV Community

Cover image for 🚀 Express.js Cheat Sheet
AK
AK

Posted on

🚀 Express.js Cheat Sheet

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);
});
Enter fullscreen mode Exit fullscreen mode

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();
});
Enter fullscreen mode Exit fullscreen mode

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 });
});
Enter fullscreen mode Exit fullscreen mode

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');
});
Enter fullscreen mode Exit fullscreen mode

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' });
});
Enter fullscreen mode Exit fullscreen mode

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' });
});
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
  });
});
Enter fullscreen mode Exit fullscreen mode

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
}));
Enter fullscreen mode Exit fullscreen mode

🔟 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
Enter fullscreen mode Exit fullscreen mode

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();
});
Enter fullscreen mode Exit fullscreen mode

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}`);
});
Enter fullscreen mode Exit fullscreen mode

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);
});
Enter fullscreen mode Exit fullscreen mode

💾 Save this cheat sheet! This covers 95% of Express.js use cases you'll encounter.

Top comments (0)