Menu
CoddyTech

嵌套路由

本课属于 Coddy Node.js 学习旅程的“Express 基础”单元。第 20 课,共 23 课。

评论属于某个食谱,因此它们的 URL 位于该食谱路径下:/api/recipes/2/reviews。

const chapters = express.Router({ mergeParams: true });

chapters.get('/', (req, res) => {
    res.json(chaptersOf(req.params.isbn));
});

app.use('/api/books/:isbn/chapters', chapters);

路由器的 req.params 只包含它自身路径中的参数。挂载路径中的 :isbn 属于应用,因此在路由器内部它的值是 undefined,除非创建路由器时使用了 mergeParams: true。

routes/reviews.js 已准备就绪,其中包含一个 reviews 对象和一个 hasRecipe(id) 辅助函数。

challenge icon

挑战

简单

访客可以为菜谱留下评价。每条评价都属于一个菜谱,因此它的 URL 位于该菜谱下:/api/recipes/1/reviews。

  1. 在 routes/reviews.js 中,让路由器能够读取挂载路径中的菜谱 id。否则,路由器中的 req.params.id 会是 undefined(请参阅课文)。
  2. 为 / 添加一个 GET 路由。它会以 JSON 列表的形式返回该菜谱的评价;如果还没有评价,则返回空列表 []。将评价存放在 reviews 对象中,每个菜谱 id 对应一个列表,例如 { "1": [{ "stars": 5, "text": "Lovely" }] }。
  3. 为 / 添加一个 POST 路由。它会从请求体中读取 stars 和 text,将评价添加到该菜谱的列表中,并返回状态码 201 和这条评价:{"stars": 5, "text": "Lovely"}。只存储并发送这两个字段。
  4. 在这两个路由中,如果 hasRecipe(id) 为 false,则返回状态码 404 和 {"error": "No such recipe"}。
  5. 在 server.js 中导入路由器,并将它挂载到 /api/recipes/:id/reviews,放在菜谱路由器旁边,并且位于 404 处理器之前。

试试看:按“运行”,然后发送 /api/recipes/1/reviews:[]。选择 POST,并向 /api/recipes/1/reviews 发送 {"stars": 5, "text": "Lovely"}:返回状态码 201 和这条评价。再次发送 GET 请求到 /api/recipes/1/reviews:[{"stars":5,"text":"Lovely"}]。发送 /api/recipes/2/reviews:仍然返回 [],因为每个菜谱都有自己的评价。发送 /api/recipes/99/reviews:返回状态码 404 和 {"error":"No such recipe"}。

亲手试试

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

// 按菜谱 id 存储评价,例如 { 1: [{ stars: 5, text: 'Lovely' }] }。
const reviews = {};

const hasRecipe = (id) => recipes.some((recipe) => recipe.id === Number(id));

const router = express.Router();

// GET / 列出某道菜谱的评价。POST / 添加一条评价。

export default router;

Express 基础中的所有课

自己练习: Express 在线编辑器