Express

Express


Introduction

Express.js is a minimal, unopinionated web framework for Node.js that provides a robust set of features for building web applications and APIs. Unlike opinionated frameworks like Nest.js, Fastify, or Django, Express gives developers more flexibility in structuring their applications.

Getting Started

Installation

npm init -y npm install express@5 npm install nodemon --save-dev

Basic Configuration

Update package.json:
{ "type": "module", "scripts": { "dev": "nodemon --watch --env-file=.env main.js", "deploy": "node main.js" } }

Server Setup

Basic Server

import express from "express"; const app = express(); const PORT = process.env.PORT || 3000; // Parse JSON bodies app.use(express.json()); // Parse URL-encoded bodies app.use(express.urlencoded({ extended: false })); app.get("/", (req, res) => { res.send("API is active"); }); app.listen(PORT, () => { console.log(`Server started on ${PORT}`); });

Health Check

app.get("/health", (req, res) => { res.status(200).json({ status: "healthy" }); });

Routing

Basic Routes

// GET request app.get("/api/items", (req, res) => { res.json({ items: [] }); }); // POST request app.post("/api/items", (req, res) => { res.status(201).json({ message: "Item created" }); }); // Dynamic routes app.get("/api/items/:id", (req, res) => { const id = parseInt(req.params.id); res.json({ id }); });

Route Parameters

  • URL Parameters: req.params
  • Query Parameters: req.query
  • Request Body: req.body

Middleware

Custom Logger Middleware

const requestLogger = (req, res, next) => { console.log(`${req.method} ${req.path} at ${new Date().toISOString()}`); next(); }; app.use(requestLogger);

Built-in Middleware

// JSON Parser app.use(express.json()); // URL-encoded Parser app.use(express.urlencoded({ extended: false })); // Static Files app.use(express.static('public')); // Compression: npm install compression import compression from 'compression'; app.use(compression());

Request & Response

Request Object

  • req.params: URL parameters
  • req.query: Query string parameters
  • req.body: Request body (for POST/PUT)
  • req.headers: Request headers
  • req.path: Request path
  • req.method: HTTP method

Response Object

// Send JSON res.json({ data: "value" }); // Send Status res.status(200).send("Success"); // Send File import path from 'path'; res.sendFile(path.join(process.cwd(), 'public', 'index.html'));

Error Handling

Custom Error Handler

const errorHandler = (err, req, res, next) => { const statusCode = err.statusCode || 500; res.status(statusCode).json({ error: { message: err.message, stack: process.env.NODE_ENV === 'production' ? 'šŸ„ž' : err.stack } }); }; // 404 Handler const notFound = (req, res, next) => { const error = new Error(`Not Found - ${req.originalUrl}`); res.status(404); next(error); }; // Use handlers app.use(notFound); app.use(errorHandler);

Best Practices

Project Structure

project/ ā”œā”€ā”€ controllers/ # Route handlers ā”œā”€ā”€ middleware/ # Custom middleware ā”œā”€ā”€ models/ # Data models ā”œā”€ā”€ routes/ # Route definitions ā”œā”€ā”€ public/ # Static files ā”œā”€ā”€ main.js # Entry point └── package.json

Route Organization

// routes/items.js import express from 'express'; const router = express.Router(); router.get('/', (req, res) => { res.json({ items: [] }); }); export default router; // main.js import itemsRouter from './routes/items.js'; app.use('/api/items', itemsRouter);

Security Best Practices

  • Always validate input
  • Use CORS middleware for cross-origin requests
  • Set security headers
  • Rate limit requests
  • Use HTTPS in production
  • Implement proper authentication/authorization

Performance Tips

  • Use compression middleware
  • Implement caching
  • Use async/await for asynchronous operations
  • Proper error handling
  • Load balancing for production

šŸ§‘šŸ»ā€šŸš€