Node.js Express Routing

Express routing decides which code runs for each incoming request, based on the HTTP method and the URL path. Good routing keeps your API predictable and your code organized.

Route Methods

app.get('/posts', (req, res) => res.send('List posts'));
app.post('/posts', (req, res) => res.send('Create post'));
app.put('/posts/:id', (req, res) => res.send('Replace post ' + req.params.id));
app.patch('/posts/:id', (req, res) => res.send('Update post ' + req.params.id));
app.delete('/posts/:id', (req, res) => res.send('Delete post ' + req.params.id));
DELETE /posts/9
Delete post 9

Route Parameters

A segment starting with a colon is a parameter. Its value appears in req.params as a string.

app.get('/users/:userId/books/:bookId', (req, res) => {
  const { userId, bookId } = req.params;
  res.json({ userId: Number(userId), bookId: Number(bookId) });
});
GET /users/4/books/17
{"userId":4,"bookId":17}

Query Strings

Values after the ? in a URL are in req.query. They are optional, so give defaults.

app.get('/search', (req, res) => {
  const { q = '', page = '1' } = req.query;
  res.json({ searchingFor: q, page: Number(page) });
});
GET /search?q=node&page=2
{"searchingFor":"node","page":2}

Reading a POST Body

Add the built-in express.json() middleware once, and JSON bodies appear in req.body.

app.use(express.json());

app.post('/contact', (req, res) => {
  const { name, email } = req.body;
  if (!name || !email) {
    return res.status(400).json({ error: 'name and email are required' });
  }
  res.status(201).json({ message: `Thanks, ${name}!` });
});
POST /contact  {"name":"Zara","email":"z@mail.com"}
{"message":"Thanks, Zara!"}

Organizing Routes with express.Router

As the app grows, put related routes in their own file with a Router, then mount it on a prefix.

// routes/products.js
import { Router } from 'express';
const router = Router();

router.get('/', (req, res) => res.json([{ id: 1, name: 'Laptop' }]));
router.get('/:id', (req, res) => res.json({ id: req.params.id }));

export default router;

// server.js
import productsRouter from './routes/products.js';
app.use('/api/products', productsRouter);
GET /api/products/1
{"id":"1"}

Routing Tips

  • Routes are matched in the order they are defined; put specific paths before generic ones.
  • Use nouns for resources (/products) and HTTP methods for actions.
  • Always validate and convert params and query values; they arrive as strings.
  • Add a final catch-all handler for 404 responses after all routes.

Frequently asked questions

What is the difference between req.params and req.query?

req.params holds named segments from the path, like :id in /users/:id. req.query holds optional key-value pairs after the ? in the URL.

Why is req.body undefined in Express?

You have not added body-parsing middleware. Add app.use(express.json()) for JSON or express.urlencoded({ extended: true }) for HTML form posts, before your routes.

What is express.Router used for?

It creates a mini-app of routes and middleware that you can put in a separate file and mount at a path prefix, keeping large apps organized.