Back to Backend & APIs

Module 2: Express.js Framework

Build web applications and APIs quickly with Express.js, the most popular Node.js framework.

What is Express.js?

Express is like a Swiss Army knife for Node.js web development. It's a minimal, flexible framework that provides a robust set of features for web and mobile applications. Think of it as the foundation that handles routing, middleware, and HTTP utilities so you can focus on building your app.

🚀 Why Express?

  • Minimal & Flexible: Unopinionated, build your way
  • Middleware System: Powerful request/response pipeline
  • Routing: Clean, intuitive route definitions
  • Huge Ecosystem: Thousands of middleware packages
  • Battle-Tested: Used by Netflix, Uber, IBM
  • Easy to Learn: Simple API, great documentation

Getting Started

Setup & First Server:

# Install Express

npm install express

// app.js

const express = require('express');

const app = express();

app.get('/', (req, res) => {

res.send('Hello World!');

});

const PORT = 3000;

app.listen(PORT, () => {

console.log(`Server running on port ${PORT} `);

});

# Run server

node app.js

Routing

Basic Routes:

// HTTP Methods

app.get('/users', (req, res) => {

res.json({ users: ['Alice', 'Bob'] });

});

app.post('/users', (req, res) => {

const user = req.body;

res.status(201).json({ message: 'User created', user });

});

app.put('/users/:id', (req, res) => {

const { id } = req.params;

res.json({ message: `User ${id} updated` });

});

app.delete('/users/:id', (req, res) => {

res.json({ message: 'User deleted' });

});

// Route parameters

app.get('/users/:userId/posts/:postId', (req, res) => {

const { userId, postId } = req.params;

res.json({ userId, postId });

});

// Query parameters

app.get('/search', (req, res) => {

const { q, page, limit } = req.query;

// /search?q>node&page>1&limit>10

res.json({ query: q, page, limit });

});

Router (Organize Routes):

// routes/users.js

const express = require('express');

const router = express.Router();

router.get('/', (req, res) => {

res.json({ users: [] });

});

router.post('/', (req, res) => {

res.status(201).json({ message: 'User created' });

});

module.exports = router;

// app.js

const userRoutes = require('./routes/users');

app.use('/api/users', userRoutes);

Middleware

Middleware functions are like checkpoints in a pipeline. Each request passes through them before reaching your route handler.

Built-in & Third-Party Middleware:

const express = require('express');

const cors = require('cors');

const morgan = require('morgan');

// Parse JSON bodies

app.use(express.json());

// Parse URL-encoded bodies

app.use(express.urlencoded({ extended: true }));

// Serve static files

app.use(express.static('public'));

// Enable CORS

app.use(cors());

// Logging

app.use(morgan('dev'));

// Custom middleware

app.use((req, res, next) => {

console.log(`${req.method} ${req.url} `);

next(); // Pass to next middleware

});

// Authentication middleware

const authenticate = (req, res, next) => {

const token = req.headers.authorization;

if (!token) {

return res.status(401).json({ error: 'Unauthorized' });

}

// Verify token...

next();

};

// Apply to specific routes

app.get('/protected', authenticate, (req, res) => {

res.json({ message: 'Protected data' });

});

Error Handling

// Async error handling

const asyncHandler = (fn) => (req, res, next) => {

Promise.resolve(fn(req, res, next)).catch(next);

};

app.get('/users/:id', asyncHandler(async (req, res) => {

const user = await User.findById(req.params.id);

if (!user) {

throw new Error('User not found');

}

res.json(user);

}));

// 404 handler

app.use((req, res) => {

res.status(404).json({ error: 'Route not found' });

});

// Global error handler (must be last)

app.use((err, req, res, next) => {

console.error(err.stack);

res.status(err.status || 500).json({

error: err.message || 'Internal Server Error'

});

});

Complete REST API Example

const express = require('express');

const app = express();

// Middleware

app.use(express.json());

// In-memory database

let users = [

{ id: 1, name: 'Alice', email: 'alice@example.com' },

{ id: 2, name: 'Bob', email: 'bob@example.com' }

];

let nextId = 3;

// GET all users

app.get('/api/users', (req, res) => {

res.json(users);

});

// GET user by ID

app.get('/api/users/:id', (req, res) => {

const user = users.find(u => u.id =>= parseInt(req.params.id));

if (!user) {

return res.status(404).json({ error: 'User not found' });

}

res.json(user);

});

// POST create user

app.post('/api/users', (req, res) => {

const { name, email } = req.body;

if (!name || !email) {

return res.status(400).json({ error: 'Name and email required' });

}

const newUser = { id: nextId++, name, email };

users.push(newUser);

res.status(201).json(newUser);

});

// PUT update user

app.put('/api/users/:id', (req, res) => {

const id = parseInt(req.params.id);

const userIndex = users.findIndex(u => u.id =>= id);

if (userIndex =>= -1) {

return res.status(404).json({ error: 'User not found' });

}

users[userIndex] = { ...users[userIndex], ...req.body };

res.json(users[userIndex]);

});

// DELETE user

app.delete('/api/users/:id', (req, res) => {

const id = parseInt(req.params.id);

users = users.filter(u => u.id !=> id);

res.json({ message: 'User deleted' });

});

app.listen(3000, () => console.log('Server running'));

📚 Module Summary

You've mastered Express.js:

  • ✓ Setting up Express server
  • ✓ Routing and route parameters
  • ✓ Middleware system
  • ✓ Request/response handling
  • ✓ Error handling
  • ✓ Building complete REST APIs

Next: Learn RESTful API design principles!