Menu
CoddyTech

Express Router

Part of the Express Basics section of Coddy's Node.js journey. Lesson 19 of 23.

server.js now holds pages, API routes and middleware, and it keeps growing.

// routes/books.js
const router = express.Router();
router.get('/', (req, res) => res.json(books));
router.get('/:isbn', (req, res) => res.json(findBook(req.params.isbn)));
export default router;

// server.js
app.use('/api/books', booksRouter);

express.Router() makes a small app with routes of its own, kept in its own file. app.use('/api/books', booksRouter) mounts it: the router's / answers GET /api/books, and its /:isbn answers GET /api/books/9780141439518. The prefix is written once, in app.use. Errors thrown inside a router still reach the app's error handler.

The new file routes/recipes.js already has one route, /tags.

challenge icon

Challenge

Easy

server.js keeps growing. Move the recipe API into its own file, routes/recipes.js, which already has a route that lists every tag.

  1. In routes/recipes.js, below the /tags route, add the four API routes from server.js: the list, one recipe by id, the POST that adds a recipe, and the scale route. Inside a router, leave out the /api/recipes part of each path: /api/recipes/:id becomes /:id, and the list becomes /.
  2. Keep them below /tags. Express tries routes in order, and /:id placed first would catch /tags and look for a recipe whose id is tags.
  3. Delete those four routes from server.js.
  4. In server.js, import the router from ./routes/recipes.js and mount it at /api/recipes with app.use, where the four routes were: after express.json() and before the 404 handler.

Try it: Press Run and send /api/recipes/tags. You should see ["breakfast","dinner","soup","sweet","vegan"]. Send /api/recipes/2: the Pancakes recipe, as before. POST {"title": "Toast"} to /api/recipes: status 201. Then send /api/recipes/5/scale?by=2: status 500 and {"error":"Something went wrong"}, so errors thrown inside the router still reach your error handler. The URLs did not change; only where the code lives did.

Try it yourself

import express from 'express';
import { recipes } from '../data.js';

const router = express.Router();

// Every tag, once, in alphabetical order.
router.get('/tags', (req, res) => {
    const tags = new Set(recipes.flatMap((recipe) => recipe.tags));
    res.json([...tags].sort());
});

// Move the /api/recipes routes from server.js here, below /tags.
// Inside a router, paths are relative to where it is mounted.

export default router;
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Express Basics

Practice on your own: Express playground