いい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つのルールをまとめると

  1. URLには名詞を使う(動詞はHTTPメソッドに任せる)
  2. 名詞は複数形にする
  3. 階層はスラッシュで表現し、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)