Express.js Basics

Web Server with Express.js

Express as API Server

Express.js is commonly used to build RESTful APIs.

// Install dependencies
npm init -y
npm install express cors

// Create api-server.js
const express = require('express');
const cors = require('cors');
const app = express();

// Middleware
app.use(cors());
app.use(express.json());

// Sample data
let todos = [
  { id: 1, text: 'Learn Express', completed: false },
  { id: 2, text: 'Build an API', completed: true }
];

// GET all todos
app.get('/api/todos', (req, res) => {
  res.json(todos);
});

// GET single todo
app.get('/api/todos/:id', (req, res) => {
  const todo = todos.find(t => t.id === parseInt(req.params.id));
  if (!todo) return res.status(404).json({ error: 'Todo not found' });
  res.json(todo);
});

// POST new todo
app.post('/api/todos', (req, res) => {
  const todo = {
    id: todos.length + 1,
    text: req.body.text,
    completed: false
  };
  todos.push(todo);
  res.status(201).json(todo);
});

// PUT update todo
app.put('/api/todos/:id', (req, res) => {
  const todo = todos.find(t => t.id === parseInt(req.params.id));
  if (!todo) return res.status(404).json({ error: 'Todo not found' });
  
  todo.text = req.body.text || todo.text;
  todo.completed = req.body.completed ?? todo.completed;
  
  res.json(todo);
});

// DELETE todo
app.delete('/api/todos/:id', (req, res) => {
  const todoIndex = todos.findIndex(t => t.id === parseInt(req.params.id));
  if (todoIndex === -1) return res.status(404).json({ error: 'Todo not found' });
  
  todos.splice(todoIndex, 1);
  res.status(204).send();
});

app.listen(3000, () => {
  console.log('API Server running on port 3000');
});

Test the API with curl:

# Get all todos
curl http://localhost:3000/api/todos

# Create a new todo
curl -X POST http://localhost:3000/api/todos \
  -H "Content-Type: application/json" \
  -d '{"text": "New todo"}'

# Update a todo
curl -X PUT http://localhost:3000/api/todos/1 \
  -H "Content-Type: application/json" \
  -d '{"completed": true}'

# Delete a todo
curl -X DELETE http://localhost:3000/api/todos/1

Express Middleware

Middleware functions have access to the request and response objects:

// Logger middleware
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

// Error handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Something broke!' });
});

Best Practices

  • Use middleware for common functionality (logging, authentication)
  • Structure routes in separate files
  • Implement proper error handling
  • Validate input data
  • Use environment variables for configuration
  • Implement rate limiting for APIs
  • Add proper security headers