付録D 読解ガイド

本書を通じて、HTTP リクエストがサーバに届いてからレスポンスが返るまでの流れを追ってきました。 フレームワークの内部動作を本当に理解するには、最終的にソースコードを読むことが最も確実な方法です。 しかし、大規模なコードベースをいきなり開いても、どこから手をつければよいか分からず挫折しがちです。

本付録では、本書で扱った 3 つのコードベースについて、「最初に読むべきファイル」と「読み進めるための道筋」を紹介します。

Tip

ソースコードを読むときは、「全部理解しよう」と焦らないことが大切です。 まずは「リクエストがどう処理されるか」という一本の流れだけを追うことから始めましょう。


Django のソースをどこから読むか

Django のソースコードは GitHub の django/django リポジトリにあり、主要なコードは django/ ディレクトリ以下に配置されています。 全体は巨大ですが、本書の内容に沿って読むなら、入口は明確です。

起点:リクエストの入口

最初に開くべきファイルは django/core/handlers/wsgi.py です。 ここに WSGIHandler クラスがあり、WSGI サーバから environstart_response を受け取って Django の処理に橋渡しする部分になっています。

__call__ メソッドがリクエストの入口であり、以下の流れが数十行で読み取れます。

  1. WSGIRequest オブジェクトを生成する

  2. self.get_response(request) を呼び出す

  3. レスポンスを返却する

本書の 2 章・3 章で解説した「WSGI とフレームワークの接続点」がまさにここです。

注釈

ASGI 側を読みたい場合は、django/core/handlers/asgi.pyASGIHandler が対応するクラスです。 scope, receive, send を受け取る構造になっており、WSGI 版と並べて読むと、同じ処理がどのように非同期化されているかが明確に分かります。

次に読む:ミドルウェアチェーン

WSGIHandler.get_response を追うと、django/core/handlers/base.pyBaseHandler にたどり着きます。 ここで押さえるべきメソッドは 2 つです。

メソッド

役割

load_middleware

settings.MIDDLEWARE のリストを逆順にたどり、各ミドルウェアをチェーンさせる

_get_response

URL 解決とビュー呼び出しの核心部分

本書の 8 章で解説したミドルウェアの「玉ねぎ構造」が、ここで実装として確認できます。

個別のミドルウェアを読むなら、django/middleware/security.pySecurityMiddleware)が最も短く読みやすいファイルです。 SECURE_SSL_REDIRECTSECURE_HSTS_SECONDS の処理が数十行で実装されており、14 章で扱ったセキュリティ設定がどう動作するかを具体的に理解できます。

django/middleware/csrf.py はより複雑ですが、CSRF トークンの生成・検証の全工程が 1 ファイルに収まっているため、14-5 章の CSRF の理解を深めるのに最適です。

URL 解決とビュー呼び出し

django/urls/resolvers.py には URLResolverURLPattern があり、resolve メソッドがリクエストパスをビュー関数にマッピングする処理を担っています。 正規表現や path コンバータがどう評価されるかをステップ実行で追うと、URL 設計の制約や優先順位が体感できます。

リクエスト・レスポンスオブジェクト

django/http/request.pyHttpRequestQueryDictdjango/http/response.pyHttpResponseJsonResponse は、本書の 4 章・5 章に直結するファイルです。

QueryDict__getitem__ で最後の値だけ返し、getlist で全値を返す仕組みは、ソースを読むと「なぜそうなっているのか」が分かります。

ORM を読むなら

ORM に踏み込む場合は django/db/models/query.pyQuerySet クラスが起点です。 filter, exclude, annotate などのメソッドが内部的に Query オブジェクト(django/db/models/sql/query.py)を組み立てていく過程が読めます。

注意

ORM のコードは複雑度が高いため、最初から全部を読もうとすると挫折しやすいです。 まずは QuerySet.__iter__ を追って「SQL がいつ発行されるか」を確認するところから始めることをおすすめします。

読む順序のまとめ

Django を読む際は、以下の順序がおすすめです。

  1. django/core/handlers/wsgi.pyWSGIHandler.__call__ でリクエストの入口を押さえる

  2. django/core/handlers/base.pyBaseHandler.load_middleware_get_response でミドルウェアと URL 解決の流れを理解する

  3. django/middleware/security.py で短いミドルウェアの実装を読む

この 3 ステップで、Django がリクエストを受け取ってからビューに到達するまでの全景が見えてきます。


FastAPI / Starlette のソースをどこから読むか

FastAPI は Starlette の上に構築されているため、実行時の HTTP 処理の大部分は Starlette のコードが担っています。 FastAPI 固有のコードは主に以下の部分に集中しています。

  • ルーティングの拡張

  • 依存性注入

  • バリデーション(Pydantic 連携)

  • OpenAPI スキーマ生成

重要

FastAPI のソースを読む際は、「いま読んでいるのは FastAPI の層か Starlette の層か」を常に意識することが重要です。 この 2 層を混同すると、どこで何が起きているか分からなくなりがちです。

起点:ASGI アプリケーションの入口

Starlette 側の入口は starlette/applications.pyStarlette クラスです。 __call__ メソッドが scope, receive, send を受け取り、ミドルウェアスタック経由でルーティングに渡す流れが読めます。

FastAPI 側では fastapi/applications.pyFastAPI クラスが Starlette を継承しており、__init__ で追加のセットアップ(ルーターの差し替え、OpenAPI 設定など)を行っています。ただし __call__ 自体は Starlette のものがそのまま使われています。

ルーティング

Starlette のルーティングは starlette/routing.py にあり、以下の 3 クラスが中心です。

クラス

役割

Route

1 つのパスとハンドラの対応を表す

Router

複数の Route をまとめ、マッチングを行う

Mount

パスのプレフィックスで別の Router をマウントする

Router.route メソッド(デコレータ)が Route オブジェクトを生成し、Router.__call__ でリクエストパスとのマッチングを行います。 マッチングのロジックは Route.matches メソッドに集約されており、パスパラメータの抽出({item_id} 形式)もここで処理されます。

FastAPI は fastapi/routing.pyAPIRouteAPIRouter を定義し、Starlette の Route / Router を拡張しています。 APIRouteget_route_handler メソッドが、リクエストのバリデーション・依存性注入・レスポンスのシリアライズを組み込んだハンドラを生成する箇所です。 FastAPI の「魔法」の多くはここに集約されています。

リクエスト・レスポンス

starlette/requests.pyRequest クラスは、ASGI の scope をラップして以下のようなインターフェースを提供します。

  • request.method — HTTP メソッド

  • request.url — リクエスト URL

  • request.headers — ヘッダー情報

  • await request.json() — JSON ボディの取得

付録 B で示した生の scope / receive 操作がどのように抽象化されているかが直接読めます。

Tip

特に await request.body() の実装は読む価値があります。 receive のチャンク受信をキャッシュする仕組みが分かり、「ボディは一度しか消費できない」という制約がどのように解決されているかが理解できます。

starlette/responses.py には Response, JSONResponse, HTMLResponse, StreamingResponse などがあり、いずれも __call__ メソッドで send を呼び出してレスポンスを送信しています。 StreamingResponse の実装は、"more_body": True を使った段階的送信の実例として読む価値があります。

ミドルウェア

starlette/middleware ディレクトリに各種ミドルウェアがあります。 starlette/middleware/cors.pyCORSMiddleware)は、本書の 14-8 章で扱った CORS の仕組みが実装レベルで確認できるファイルです。 以下のような処理が読めます。

  • プリフライトリクエスト(OPTIONS)の処理

  • Access-Control-Allow-Origin ヘッダーの生成ロジック

  • ワイルドカード *allow_credentials の排他制御

依存性注入

FastAPI の依存性注入は fastapi/dependencies/utils.pyfastapi/dependencies/models.py に実装されています。 get_dependant 関数がエンドポイントの型ヒントを解析し、Dependant オブジェクトのツリーを構築する過程が読めます。

難易度について

class: caution

このコードはメタプログラミングが多用されており、難度は高めです。 ただし、Depends() がどのように解決されるかを理解するうえで避けて通れない部分でもあります。 最初は「大まかな流れをつかむ」ことを目標に、細部は後回しにしてもよいでしょう。

読む順序のまとめ

FastAPI / Starlette を読む際は、以下の順序がおすすめです。

  1. starlette/applications.pyStarlette.__call__ で ASGI の入口を押さえる

  2. starlette/routing.pyRouter.__call__Route.matches でルーティングの仕組みを理解する

  3. starlette/requests.pyRequest クラスで scope / receive の抽象化を確認する

  4. fastapi/routing.pyAPIRoute.get_route_handler で FastAPI 固有の拡張を読む


Werkzeug のソースをどこから読むか

Werkzeug は Flask の基盤となっている WSGI ユーティリティライブラリです。 Flask 自体のコードは比較的薄く、HTTP の処理やリクエスト/レスポンスのパース、URL ルーティング、開発サーバなど、重い処理の多くは Werkzeug が担っています。

Flask のソースを読みたい場合も、最終的に Werkzeug のコードにたどり着くことが多いため、Werkzeug を直接読む技術は Flask 理解の土台となります。

起点:リクエストとレスポンス

最初に読むべきファイルは werkzeug/wrappers/request.pywerkzeug/wrappers/response.py です。

Request クラスは WSGI の environ 辞書をラップし、以下のような使い慣れたインターフェースを提供します。

  • request.method — HTTP メソッド

  • request.args — クエリパラメータ

  • request.form — POST データ

  • request.headers — ヘッダー情報

Request クラスの中で特に読む価値があるのは args プロパティの実装です。 environ["QUERY_STRING"]MultiDict にパースする過程が追えます。

注釈

MultiDictwerkzeug/datastructures/structures.py)は Django の QueryDict に相当するデータ構造です。 同一キーに複数の値が送られてきた場合にどう扱うかという設計思想が読み取れます。 たとえば、フォームで同じ名前のチェックボックスが複数ある場合などがこれにあたります。

Response クラスは __call__(environ, start_response) メソッドを持っており、それ自体が WSGI アプリケーションとして振る舞えるという設計になっています。 Content-TypeContent-Length の自動設定、Set-Cookie ヘッダーの構築などがこのクラスに集約されています。

URL ルーティング

werkzeug/routing/map.pyMap クラスと werkzeug/routing/rules.pyRule クラスが URL ルーティングの中心です。

クラス/メソッド

役割

Map

全 URL ルールを管理するコンテナ

Rule

個別のパスパターンと HTTP メソッドの対応を表す

Map.bind

リクエスト情報にバインドした MapAdapter を生成する

MapAdapter.match

パスと HTTP メソッドに基づいてルールをマッチングする

Flask の @app.route("/users/<int:user_id>") がどう動くかを知りたければ、以下を順番に読むと全体像がつながります。

  1. Rule.__init__ でパスパラメータがどうパースされるか

  2. werkzeug/routing/converters.pyIntegerConverterUnicodeConverter がどう型変換するか

開発サーバ

werkzeug/serving.py は、Flask の app.run() で起動する開発サーバの実装です。 Python 標準ライブラリの http.server をベースに、マルチスレッド対応やオートリロード機能を追加しています。

警告

本書の 14-7 章で「開発サーバを本番利用してはいけない」と述べましたが、その理由がソースレベルで確認できます。 以下のような本番には不適切な特性がコードから読み取れます。

  • シングルスレッドのリクエスト処理

  • デバッグ用のトレースバック表示(エラー内容がブラウザに丸見えになる)

  • TLS 対応の簡素さ

run_simple 関数を追うと、リクエストが到着してからレスポンスが返るまでの全工程が 1 ファイルで完結しており、WSGI サーバの最小実装として非常に教育的です。 付録 A で書いた最小 WSGI アプリが、実際のサーバ上でどのように呼ばれるかを具体的に理解できます。

デバッガ

werkzeug/debug/__init__.pyDebuggedApplication は、例外発生時にブラウザ上でインタラクティブな Python コンソールを提供する WSGI ミドルウェアです。 これは開発時には便利ですが、本番で有効にすると任意のコード実行が可能になるため、重大な脆弱性となります。

このミドルウェアのコードを読むと、「ミドルウェアで例外をキャッチし、通常とは異なるレスポンスを返す」というパターンの実例として理解でき、同時にセキュリティリスクの具体性も体感できます。

読む順序のまとめ

Werkzeug を読む際は、以下の順序がおすすめです。

  1. werkzeug/wrappers/request.pyRequest クラスで environ の抽象化を理解する

  2. werkzeug/routing/rules.pyRulewerkzeug/routing/map.pyMap で URL ルーティングの仕組みを把握する

  3. werkzeug/serving.pyrun_simple で開発サーバの全体像を確認する

この 3 ステップを経ると、Flask のコード(flask/app.pyFlask クラス)は、これらの Werkzeug コンポーネントを組み立てる薄いレイヤーとして読めるようになります。


ソースコードを読むための実践的なテクニック

3 つのコードベースに共通する、ソース読解の実践的なアプローチを最後に紹介します。

1. リクエストの入口から追う

どのフレームワークも __call__ メソッドが入口です。そこから printbreakpoint() を挟みながら実行フローを追うのが最も確実な方法です。 python -m pdb や IDE のデバッガで、実際にリクエストを送りながらステップ実行すると、呼び出し順序とデータの変化が手に取るように分かります。

2. git log と git blame を活用する

あるコードがなぜそう書かれているかは、コミットメッセージや関連する Issue・PR に書かれていることが多いです。 特にセキュリティ修正のコミットは脆弱性の具体的な攻撃手法と対策が記録されており、14 章の内容を深く理解する助けになります。

3. テストコードを先に読む

テストはそのコードが「何をすべきか」を宣言的に示しています。実装コードを読む前にテストを読むと、期待される振る舞いが把握できます。

フレームワーク

テストの場所

Django

tests/ ディレクトリ

Starlette

tests/ ディレクトリ

Werkzeug

tests/ ディレクトリ

重要

ソースコードを読む力は一朝一夕には身につきません。 しかし、本書で得た HTTP・WSGI/ASGI・ミドルウェア・セキュリティの知識があれば、コードの意図を推測するための土台は十分に整っています。 まずは上記の「最初に読むべきファイル」を 1 つ開くところから始めてみてください。