URL ルーティング

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

URL ルーティング

このレッスンで分かること

  • Web アプリのコードを整理する古典的な設計が MVC(Model–View–Controller)です
  • ブラウザから来た URL を、対応する ControllerAction(メソッド)に振り分ける 機構を ルーティング(routing) と呼びます
  • 図のポイント (テキスト併記)

URL ルーティング とは

URL パスを Controller#action の文字列に振り分けるルーティングを実装し、MVC の「Controller の入口」を体感します。

Web アプリのコードを整理する古典的な設計が MVC(Model–View–Controller)です。3 つの役割が次のように分担されます。

  • Model — DB との読み書きやビジネスロジック
  • View — HTML テンプレートや JSON 整形
  • Controller — HTTP リクエストを受け取り、Model と View をつなぐ司令塔

ブラウザから来た URL を、対応する ControllerAction(メソッド)に振り分ける 機構を ルーティング(routing) と呼びます。Rails、Laravel、Django、Express、Hono、すべてのフレームワークが似た仕組みを持っています。

diagram (will load when visible)

図のポイント (テキスト併記)

  • ルーターは「玄関の受付」

ルーターは「玄関の受付」。お客さん(リクエスト)の行き先(Controller)を判定して取り次ぐ係。

REST 的な URL の組み立てかた

REST というスタイルでは、URL を 「リソース名 / ID / アクション」 の構造に揃えます。users リソースを例にした典型的なパターンが次の通りです。

URLController#action用途
/usersUsers#index一覧表示
/users/42Users#show詳細表示
/users/newUsers#new新規作成フォーム
/users/42/editUsers#edit編集フォーム

リソース名(users)を Users に頭文字大文字化、Controller 名にすることで「Users#show」のように一意に決まります。

コードでの考え方

今回の課題では、URL 文字列を受け取り、次のルールで Controller#action 文字列を返します。

  • /<resource><Resource>#index
  • /<resource>/new<Resource>#new
  • /<resource>/<id>id は数字または new 以外の文字列)→ <Resource>#show
  • /<resource>/<id>/edit<Resource>#edit
  • それ以外 → "404"

リソース名の頭文字を大文字に変換するヘルパーが必要です。Python なら .capitalize()、JavaScript なら s[0].toUpperCase() + s.slice(1) で書けます。

Python

def route(url): parts = url.strip("/").split("/") if len(parts) == 1 and parts[0]: return f"{parts[0].capitalize()}#index" if len(parts) == 2: resource, second = parts if second == "new": return f"{resource.capitalize()}#new" return f"{resource.capitalize()}#show" if len(parts) == 3 and parts[2] == "edit": return f"{parts[0].capitalize()}#edit" return "404"

url.strip("/") で前後のスラッシュを落としてから split("/") するのが定石。これで /users//users が同じになる。

よくある間違い

先頭のスラッシュを取り除かずに split する と、"".split("/") の結果に空文字が混じってインデックスがズレます。strip("/") または最後のスラッシュの除去を必ず先にやりましょう。

また、newedit の判定をリソース名の比較より先にやらない と、/users/edit のような変則 URL で誤判定します。今回の課題では parts[1] == "new"show 判定より前に置く必要があります。

より本格的なルーター

本物の Web フレームワークでは、/users/:id のような プレースホルダー を含む URL パターンを登録して、パラメータ(id)を Controller の引数に渡します。さらに HTTP メソッド(GET POST PUT DELETE)も加味して、POST /users なら Users#createDELETE /users/42 なら Users#destroy のようにマッピングします。今回はその前段の 「URL → Controller#action」 だけを切り出した最小モデルです。

ルーティングを理解すると、Web フレームワークが何をやっているのかが急に見えてくる。

やってみよう

上記のルールに従って route(url) を実装してください。url には /users, /users/42, /users/new, /users/42/edit, /posts/9, /posts/9/edit などが入り、Users#show のような文字列を返します。マッチしないものは "404" を返してください。

よくある質問

Q. このトピックを覚える意味は何ですか?

A. フレームワークが「裏で何をやっているか」を理解する土台になります。Rails・Laravel・Express などどのフレームワークを使っても、ルーターがリクエストを受け取り Controller に振り分ける仕組みは共通です。この構造を知っておくと、新しいフレームワークを習得するときの学習コストが大きく下がります。

Q. 実務でこの知識を使う場面は?

A. 新しい API エンドポイントを追加するとき、URL 設計とルーティング定義は必ずセットで行います。REST の命名規則(/users/:id など)を守るとチーム内の認識が揃い、ドキュメントを書かなくても URL を見ただけで用途が伝わります。また、フレームワークのルーターが生成するエラー(404/405)のデバッグにも直結します。

Q. 他の章とどう繋がりますか?

A. 次のレッスンで扱う「疎結合と密結合」に直接つながります。Controller と Model を分離するのは疎結合の典型例です。また、ルーターが URL と処理を対応づける仕組みは、後続の「依存性注入」「ミドルウェア」の理解にも生きてきます。MVC を軸に周辺概念が自然と繋がっていきます。

次のレッスン

次は 疎結合と密結合 — 依存性注入で設計を変える に進みましょう。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. MVC ルーティング の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. MVC ルーティング とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. URL を / で分割し、空要素を捨ててから判定する
  2. リソース名の頭文字を大文字に変換する(usersUsers
  3. ルールにマッチしない URL は '404' を返す

入出力例

test-cases.txt

route("/users")"Users#index" route("/users/42")"Users#show" route("/users/new")"Users#new" route("/users/42/edit")"Users#edit" route("/posts/9")"Posts#show" route("/posts/9/edit")"Posts#edit" route("/users/42/foo")"404" route("/")"404" route("/users/")"Users#index"

ヒント

main.py
main.py
学習モード

メモ

URL ルーティング

⌘S で保存