いいURLの設計 — RESTfulという考え方
バイブコーディング入門 — 第5回
前回のおさらいと、今回のテーマ
前回(第4回)では、URLを5つのパーツに分解した。スキーム、ドメイン、パス、クエリパラメータ、フラグメント。特にパスの部分が重要で、Next.jsではファイルの置き場所がそのままURLのパスになることを学んだ。
今回のテーマは、URLの「名前の付け方」だ。
URLには、良い名前と悪い名前がある。たとえば、ユーザー一覧を表示するページのURL。次の2つを比べてみてほしい。
A: /api/getUserList?type=active&format=json B: /api/users?status=active
どちらも「有効なユーザーの一覧を取得する」という同じ目的のURLだ。でも、Bのほうが読みやすいと感じたのではないだろうか。
この「読みやすさ」は偶然ではない。URLの名前の付け方には、Web業界で広く共有されている設計のルール(お作法)がある。それがRESTful(レストフル)という考え方だ。
CursorやClaude Codeは、このルールを知っている。だから、AIに任せればそれなりに良いURLを設計してくれる。でも、あなた自身がこのルールを知っていると、AIへの指示がより的確になり、生成されるコードの品質が上がる。
URLの名前は「お店の案内表示」だ
大きなショッピングモールに入ったとき、フロアガイドを見るはずだ。「1階: 食品」「2階: 衣類」「3階: 家電」。こういう案内があれば、目的の売り場にすぐたどり着ける。
もしフロアガイドが「A-01区画」「B-02区画」「C-03区画」だったらどうだろう。何がどこにあるか分からない。毎回スタッフに聞かないといけない。
URLの名前は、このフロアガイドと同じだ。良い名前をつければ、URLを見ただけで「何があるか」が想像できる。悪い名前をつけると、中身を確認するまで何のページか分からない。
RESTfulという考え方は、URLのフロアガイドをどう書くかのルールだ。
RESTfulの3つの基本ルール
RESTful(レストフル)という言葉は、REST(レスト)という設計原則に従っているという意味だ。第3回で触れたREST APIの「REST」と同じものだ。
技術的には多くの原則があるが、バイブコーディングで知っておくと役立つのは次の3つだ。
ルール1: URLには名詞を使う(動詞を使わない)
良いURLと悪いURLを比べてみよう。
悪い例: /getUsers(ユーザーを取得する) /deleteProduct(商品を削除する) /createOrder(注文を作成する)
良い例: /users(ユーザー) /products(商品) /orders(注文)
悪い例には、get(取得する)、delete(削除する)、create(作成する)という動詞が入っている。良い例は、users、products、ordersという名詞だけだ。
なぜ動詞を使わないのか。「何をするか」はURLではなく、HTTPメソッド(第1回で学んだGET、POST、PUT、DELETE)で表現するからだ。
- GET /users → ユーザーの一覧を取得する
- POST /users → 新しいユーザーを作成する
- PUT /users/123 → ID 123のユーザーの情報を更新する
- DELETE /users/123 → ID 123のユーザーを削除する
URLは「何を」、HTTPメソッドは「どうする」を担当する。役割分担だ。
ショッピングモールに例えると、フロアガイドには「食品」「衣類」「家電」と書く。「食品を買う場所」「衣類を見る場所」とは書かない。何があるか(名詞)だけを示し、そこで何をするか(動詞)は訪れる人が決める。
ルール2: 複数形を使う
悪い例: /user /product /order
良い例: /users /products /orders
URLのパスは複数形が一般的だ。/users は「ユーザーの集まり」を表し、/users/123 は「その中の1人」を表す。
ショッピングモールのフロアガイドで「1階: 食品」と書いてあれば、食品売り場にはたくさんの食品が並んでいると想像できる。「1階: 食品1個」とは書かない。URLも同じで、コレクション(集まり)を表すときは複数形を使う。
ルール3: 階層はスラッシュで表現する
URLは /(スラッシュ)で階層を表現する。前回学んだパスの仕組みだ。
/users→ ユーザーの一覧/users/123→ ID 123のユーザー/users/123/orders→ ID 123のユーザーの注文一覧/users/123/orders/456→ ID 123のユーザーの、注文番号456の詳細
左から右に、大きな範囲から小さな範囲に絞り込んでいく。住所の「東京都 → 渋谷区 → 神南」と同じ構造だ。
ただし、階層は深くしすぎないほうが良い。目安として3階層まで。/users/123/orders/456/items/789/details のように深くなると、URLが長くなりすぎて扱いにくくなる。
3つのルールをまとめると
- URLには名詞を使う(動詞はHTTPメソッドに任せる)
- 名詞は複数形にする
- 階層はスラッシュで表現し、3階層までに抑える
この3つを覚えておけば、URLの設計で迷うことはほぼなくなる。
実際のWebサービスのURLを読んでみよう
3つのルールを知った上で、普段使っているWebサービスのURLを見てみよう。
GitHub: /users/tanaka(ユーザーtanakaのプロフィール) /users/tanaka/repos(ユーザーtanakaのリポジトリ一覧)
Amazon: /products/B09ABCDEFG(特定の商品ページ)
X(旧Twitter): /settings/account(設定の中のアカウント設定)
名詞が使われていて、スラッシュで階層が区切られている。RESTfulの原則に沿っていることが分かる。
これが「読める」ようになると、初めて訪れるサイトでもURLを見ただけで「このページは何を表示しているか」が想像できるようになる。
CursorやClaude CodeにURLを指示するコツ
RESTfulの考え方を知っていると、AIへの指示が格段に具体的になる。
具体例を見てみよう。ECサイトの商品管理機能をAIに作ってもらうとする。
曖昧な指示
「商品の管理画面を作って」
この指示だと、AIは何を作ればいいか分からない。一覧ページだけ作るかもしれないし、編集機能まで含めるかもしれない。URLの構造もAI任せになる。
RESTfulを意識した指示
「商品管理機能を作ってほしい。URL構造は次の通り。
ページ:
- /products → 商品一覧ページ
- /products/[id] → 商品詳細ページ
- /products/new → 商品登録ページ
- /products/[id]/edit → 商品編集ページ
API:
- GET /api/products → 商品一覧を取得
- GET /api/products/[id] → 特定の商品を取得
- POST /api/products → 新しい商品を登録
- PUT /api/products/[id] → 商品情報を更新
- DELETE /api/products/[id] → 商品を削除」
この指示なら、AIはURL構造で迷わず、正しいファイル構成でコードを生成してくれる。前回学んだファイルベースルーティングの知識と組み合わせると、次のフォルダ構造が自動的に作られる。
app/ products/ page.tsx → /products(一覧) new/ page.tsx → /products/new(登録) [id]/ page.tsx → /products/123(詳細) edit/ page.tsx → /products/123/edit(編集) api/ products/ route.ts → GET, POST /api/products [id]/ route.ts → GET, PUT, DELETE /api/products/123
URL設計を先に決めてからAIに渡す。これだけで、生成されるコードの一貫性が大きく向上する。
CRUD — データ操作の4パターン
RESTfulなURL設計では、データに対する操作が4つのパターンに集約される。これをCRUD(クラッド)と呼ぶ。
- Create(作成)→ POST /api/products → 新しい商品を登録する
- Read(読み取り)→ GET /api/products → 商品の一覧や詳細を取得する
- Update(更新)→ PUT /api/products/123 → 既存の商品情報を書き換える
- Delete(削除)→ DELETE /api/products/123 → 商品を削除する
Create、Read、Update、Deleteの頭文字を取ってCRUD。ほとんどのWebアプリの機能は、このCRUDの組み合わせで表現できる。
ToDoアプリなら「タスクの作成・一覧表示・完了に変更・削除」。ブログなら「記事の投稿・閲覧・編集・削除」。ECサイトなら「商品の登録・検索・情報更新・削除」。
AIに機能を依頼するとき「CRUDで作って」と言うだけで、この4つの操作に対応するAPIとページを一式生成してくれる。RESTfulなURL設計と組み合わせると、こうなる。
C: POST /api/tasks → タスクを作成 R: GET /api/tasks → タスク一覧を取得 R: GET /api/tasks/1 → タスク1の詳細を取得 U: PUT /api/tasks/1 → タスク1を更新 D: DELETE /api/tasks/1 → タスク1を削除
HTTPメソッド(POST、GET、PUT、DELETE)とURL(/api/tasks)の組み合わせだけで、何をしているかが分かる。これがRESTfulの強みだ。
よくある不安と答え
RESTfulのルールを完璧に守らないといけないのか?
守らなくても動く。URLに動詞を使っても、単数形を使っても、アプリは正常に機能する。ただし、ルールに従ったURLのほうが「読みやすい」「チームで共有しやすい」「AIが理解しやすい」というメリットがある。完璧を目指す必要はないが、意識しておくと後々ラクになる。
/api/がつくURLとつかないURLの違いは何か?
/api/ がつくURLは、データのやりとり専用(API)だ。HTMLのページではなく、JSONデータを返す。/api/ がつかないURLは、ページの表示用だ。ブラウザで直接アクセスしたときに画面が表示される。
/products→ 商品一覧ページ(HTMLが返る)/api/products→ 商品データ(JSONが返る)
どちらも「商品」を扱っているが、返すものが違う。CursorやClaude Codeでは、この2つを別々のファイルで管理する。ページは page.tsx、APIは route.ts というファイル名だ。
RESTful以外の設計方法もあるのか?
ある。GraphQL(グラフキューエル)やgRPC(ジーアールピーシー)といった方法もある。ただし、CursorやClaude Codeでアプリを作る場合、ほとんどの場合はREST APIが使われる。他の方法を知る必要が出てくるのは、かなり大規模なアプリを作るときだ。今は「RESTfulが標準的な方法」と理解しておけば十分だ。
URLの設計はAIに任せてもいいのか?
任せても大丈夫だ。CursorやClaude Codeは、RESTfulの原則を理解しているので、それなりに良いURLを設計してくれる。ただし、あなたがURL構造を明示的に指示すると、AIが迷う余地がなくなり、より一貫性のあるコードが生成される。「任せても動くが、指示すると品質が上がる」という関係だ。
まとめ
URLには良い名前の付け方がある。RESTfulという考え方に基づく3つのルール。名詞を使う、複数形にする、スラッシュで階層を表現する。データの操作はCRUD(作成・読み取り・更新・削除)の4パターンに集約され、HTTPメソッド(POST、GET、PUT、DELETE)で表現する。AIにアプリを作ってもらうとき、URL構造を先に設計して渡すだけで、生成されるコードの品質と一貫性が大きく向上する。
次回は「データの入れ物 — JSONの読み方」。Webアプリの中でデータがどのような形でやりとりされているのか、JSONという形式の読み方を解説する。
参考リファレンス
- MDN Web Docs「HTTPメソッド」— GET、POST、PUT、DELETEの仕様に関する公式リファレンス
- 前回: 第4回「URLの読み方 — アドレスバーの文字列を分解してみる」(/articles/vc-004)
- 次回: 第6回「データの入れ物 — JSONの読み方」(/articles/vc-006)
- バイブコーディング入門 カリキュラム(/vibe-coding)




