※備忘録用。誤った記載があるかもしれません。コメントで教えていただければ嬉しいです
DBに当たるものを直書きで用意してみる
typeは適当に定義し、それの配列としてramenListを作成
export type Ramen = {
id: string;
name: string;
image?: string;
custom?: {
volume: string;
toppings: string;
};
description?: string;
};
const ramenList: Ramen[] = [
{
id: "1",
name: "Shoyu Ramen",
image: "/images/shoyu-ramen.jpg",
description:
"Shoyu ramen is a Japanese noodle soup that is flavored with soy sauce. It is one of the most popular and classic ramen in Japan.",
},
{
id: "2",
name: "Miso Ramen",
image: "/images/miso-ramen.jpg",
description:
"Miso ramen is a Japanese noodle soup that is flavored with miso. It is one of the most popular and classic ramen in Japan.",
},
{
id: "3",
name: "Tonkotsu Ramen",
image: "/images/tonkotsu-ramen.jpg",
description:
"Tonkotsu ramen is a Japanese noodle soup that is flavored with pork bone broth. It is one of the most popular and classic ramen in Japan.",
},
];
APIを作ってみる
DBから値を取得したり値を追加したりする関数を、先ほどのファイルに追記
export function getRamenList(): Ramen[] {
return ramenList;
}
export function getRamenById(id: string): Ramen | undefined {
return ramenList.find((ramen) => ramen.id === id);
}
export function addRamen(ramen: Ramen) {
ramenList.push(ramen);
}
export function deleteRamen(id: string) {
const index = ramenList.findIndex((ramen) => ramen.id === id);
if (index !== -1) {
ramenList.splice(index, 1);
}
}
export function updateRamen(ramen: Ramen) {
const index = ramenList.findIndex((r) => r.id === ramen.id);
if (index !== -1) {
ramenList[index] = ramen;
}
}
先ほどの関数を、各メソッドで呼び出すよう実装。
index.tsにはデータ全てを取得したり削除したりする処理を記述。
id指定で操作したい内容は、後の[id].tsに記載。
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
//api配下のファイルは1つ1つがAPIエンドポイントとして機能する
import type { NextApiRequest, NextApiResponse } from "next";
import type { Ramen } from "@/db/ramen";
import { addRamen, getRamenList } from "@/db/ramen";
//習慣としてhandlerという名前にしている
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Ramen[]>
) {
if (req.method === "GET") {
res.status(200).json(getRamenList());
} else if (req.method === "POST") {
const ramen = req.body as Ramen;
addRamen(ramen);
res.status(201).json([ramen]);
} else {
//一括削除の時などの処理をここに書く
res.status(404).end();
}
}
[id].tsでは、id指定でデータ取得・削除などできるようにする
[id].tsのファイル名にすることで、動的パラメータを持つAPIエンドポイントを作成できる。
/api/ramen/の後ろに入る値が、req.queryで取得される。
import type { NextApiRequest, NextApiResponse } from "next";
import type { Ramen } from "@/db/ramen";
import { getRamenById, deleteRamen, updateRamen } from "@/db/ramen";
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Ramen | undefined>
) {
const { id } = req.query;
if (!id || Array.isArray(id) || id.length === 0) {
res.status(400).end();
return;
}
if (req.method === "GET") {
const ramen = getRamenById(id);
if (ramen) {
res.status(200).json(ramen);
} else {
res.status(404).end();
}
} else if (req.method === "PUT") {
const ramen = req.body as Ramen;
if (ramen.id !== id) {
res.status(400).end();
return;
}
updateRamen(ramen);
res.status(200).json(ramen);
} else if (req.method === "DELETE") {
deleteRamen(id);
res.status(204).end();
} else {
res.status(404).end();
}
}
※importで@を使うためには、以下のようにエイリアスを設定しておく。
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
APIを叩いてみる
GETは、単にブラウザのURLに入れればOK
GET api/ramen
http://localhost:8888/api/ramen
※3000番は他で使っているため、package.json
に"dev": "next dev -p 8888"
と設定してある
※http://localhost:8888/api/ramen で開いたときにhandler内のGETメソッドが実行されるのは、Next.jsのAPIルート機能によるもの。exportされている関数を実行する。Next.jsでは、pages/apiディレクトリ内に配置されたファイルは、サーバー側で実行されるAPIエンドポイントとして扱われる
他のメソッドは、Postmanで試す。