ネストされたルート
CoddyのNode.jsジャーニー「Expressの基礎」セクションの一部。レッスン 20/23。
レビューは1つのレシピに属するため、その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) ヘルパーがあります。
チャレンジ
簡単訪問者はレシピにレビューを投稿できます。レビューは1つのレシピに属するため、そのURLはレシピの下にあります: /api/recipes/1/reviews。
routes/reviews.jsで、ルーターがマウントされているパスからレシピIDを読み取れるようにします。そうしないと、ルーター内のreq.params.idはundefinedになります(レッスンの説明を参照)。/のGETルートを追加します。対象レシピのレビューをJSONリストとして返し、まだレビューがない場合は空のリスト[]を返します。レビューはreviewsオブジェクトに保持し、レシピIDごとに1つのリストを用意します。例:{ "1": [{ "stars": 5, "text": "Lovely" }] }。/のPOSTルートを追加します。本文からstarsとtextを読み取り、対象レシピのリストにレビューを追加して、ステータス201とレビューを返します:{"stars": 5, "text": "Lovely"}。この2つのフィールドだけを保存して送信します。- 両方のルートで、
hasRecipe(id)がfalseの場合は、ステータス404と{"error": "No such recipe"}を返します。 server.jsでルーターをインポートし、レシピルーターの隣、404ハンドラーの前に、/api/recipes/:id/reviewsでマウントします。
試してみましょう:「実行」を押して、/api/recipes/1/reviewsを送信します: []。POSTを選び、{"stars": 5, "text": "Lovely"}を/api/recipes/1/reviewsに送信します: ステータス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 / はレビューを1件追加します。
export default router;
Expressの基礎のすべてのレッスン
自分で練習してみよう: Expressプレイグラウンド