IntroductionGetting StartedInstallationBasic ConfigurationServer SetupBasic ServerHealth CheckRoutingBasic RoutesRoute ParametersMiddlewareCustom Logger MiddlewareBuilt-in MiddlewareRequest & ResponseRequest ObjectResponse ObjectError HandlingCustom Error HandlerBest PracticesProject StructureRoute OrganizationSecurity Best PracticesPerformance Tips
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
š§š»āš