0%
Express.js Middleware & Routing: Your Friendly Guide to Building APIs

Express.js Middleware & Routing: Your Friendly Guide to Building APIs

Learn how Express middleware and routing work together to create clean, maintainable Node.js apps. Easy examples and pro tips included!

Saransh Pachhai
Saransh Pachhai
4 min read9 viewsDecember 13, 2025
express.jsmiddlewareroutingnode.jsweb development
Share:

What’s Express Middleware and Routing?

Think of Express as a pizza shop. Middleware are the chefs who prepare ingredients, add sauce, bake the pie, etc. Routing is the menu that tells the chefs what to make. Together they turn a list of code into a web‑app that users can visit.

Why Do You Need Middleware?

Middleware is a function that sits between the request coming in and the final route handler. It can read data, add data, or decide what to do next. Common uses:

  • Parsing JSON bodies
  • Logging requests
  • Authenticating users
  • Handling errors
  • Serving static files

Because middleware runs in order, you can stack many of them to build a pipeline.

Getting Started: Build a Tiny Express App

const express = require('express');
const app = express();
const PORT = 3000;

// 1️⃣ Parse JSON bodies
app.use(express.json());

// 2️⃣ Simple logger middleware
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next(); // Pass control to the next middleware/route
});

// 3️⃣ A basic route
app.get('/', (req, res) => {
  res.send('Hello, Express!');
});

app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

Run node index.js and visit http://localhost:3000. You’ll see the log message in your terminal and “Hello, Express!” in the browser.

Routing Basics

Routes tell Express what to do for a given URL path and HTTP verb (GET, POST, etc.). Here’s a quick cheat sheet:

  • app.get(path, handler) – read data
  • app.post(path, handler) – create data
  • app.put(path, handler) – update data
  • app.delete(path, handler) – delete data

Routes can be grouped with express.Router() for clean, modular code.

Using a Router: Todo API Example

// routes/todos.js
const express = require('express');
const router = express.Router();

let todos = [
  { id: 1, title: 'Learn Express', completed: false },
  { id: 2, title: 'Build an API', completed: false }
];

// GET /todos – list all
router.get('/', (req, res) => {
  res.json(todos);
});

// POST /todos – add new
router.post('/', (req, res) => {
  const { title } = req.body;
  const newTodo = { id: todos.length + 1, title, completed: false };
  todos.push(newTodo);
  res.status(201).json(newTodo);
});

// PUT /todos/:id – update a todo
router.put('/:id', (req, res) => {
  const id = parseInt(req.params.id, 10);
  const todo = todos.find(t => t.id === id);
  if (!todo) return res.sendStatus(404);
  todo.completed = !todo.completed;
  res.json(todo);
});

module.exports = router;

Now wire it into your main app:

const express = require('express');
const todoRoutes = require('./routes/todos');
const app = express();
const PORT = 3000;

app.use(express.json());
app.use('/todos', todoRoutes); // All routes start with /todos

app.listen(PORT, () => console.log(`API running at http://localhost:${PORT}`));

Try hitting GET http://localhost:3000/todos with a tool like Insomnia or curl and watch the JSON appear.

Advanced Middleware: Auth + Error Handling

Real apps need security. Let’s add a simple “auth” middleware that checks a custom header.

// middleware/auth.js
module.exports = function (req, res, next) {
  const token = req.headers['x-access-token'];
  if (token === 'secret123') {
    next(); // Authorized
  } else {
    res.status(401).json({ error: 'Unauthorized' });
  }
};

Use it on the todo routes:

const auth = require('../middleware/auth');
router.use(auth); // All /todos endpoints now require the token

For error handling, create a catch‑all middleware at the end of your file:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Something went wrong!' });
});

Actionable Takeaways

  1. Start every Express app with express.json() to parse JSON bodies.
  2. Keep middleware simple: one job, one line. It makes debugging easier.
  3. Use express.Router() for large projects. It keeps routes readable.
  4. Stack middleware in the order you want it to run. Order matters!
  5. Always add a global error handler at the bottom of your middleware stack.

Express middleware and routing are the backbone of any Node.js web app. With a few lines of code and a clear structure, you can build fast, maintainable APIs that feel like a breeze. Happy coding!

Loading comments...

Designed & developed with❤️bySaransh Pachhai

©2025. All rights reserved.