嵌套路由
本课属于 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) 辅助函数。
挑战
简单访客可以为菜谱留下评价。每条评价都属于一个菜谱,因此它的 URL 位于该菜谱下:/api/recipes/1/reviews。
- 在
routes/reviews.js中,让路由器能够读取挂载路径中的菜谱 id。否则,路由器中的req.params.id会是undefined(请参阅课文)。 - 为
/添加一个 GET 路由。它会以 JSON 列表的形式返回该菜谱的评价;如果还没有评价,则返回空列表[]。将评价存放在reviews对象中,每个菜谱 id 对应一个列表,例如{ "1": [{ "stars": 5, "text": "Lovely" }] }。 - 为
/添加一个 POST 路由。它会从请求体中读取stars和text,将评价添加到该菜谱的列表中,并返回状态码 201 和这条评价:{"stars": 5, "text": "Lovely"}。只存储并发送这两个字段。 - 在这两个路由中,如果
hasRecipe(id)为 false,则返回状态码 404 和{"error": "No such recipe"}。 - 在
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 在线编辑器