コンテンツへスキップ

代替、インスピレーション、および比較

FastAPI がどのようにインスピレーションを受けたか、代替案と比較してどうであるか、そしてそれらから何を学んだか。

はじめに

FastAPI は、他者の先行研究がなければ存在しえませんでした。

その創造を触発した多くのツールがこれまで作成されてきました。

私は数年間、新しいフレームワークの作成を避けてきました。まず、FastAPI がカバーするすべての機能を、多くの異なるフレームワーク、プラグイン、ツールを使用して解決しようと試みました。

しかし、ある時点で、これらすべての機能を提供し、以前のツールの最良のアイデアを取り入れ、これまで利用できなかった言語機能 (Python 3.6 以降の型ヒント) を使用して、可能な限り最良の方法でそれらを組み合わせるものを作成する以外の選択肢はありませんでした。

以前のツール

Django

最も人気のあるPythonフレームワークであり、広く信頼されています。Instagramのようなシステムを構築するために使用されています。

リレーショナルデータベース (MySQLやPostgreSQLなど) と比較的密接に結合されているため、NoSQLデータベース (Couchbase、MongoDB、Cassandraなど) を主要なストレージエンジンとして使用することはあまり簡単ではありません。

これは、最新のフロントエンド (React、Vue.js、Angularなど) や、それと通信する他のシステム (IoTデバイスなど) で使用されるAPIを作成するためではなく、バックエンドでHTMLを生成するために作成されました。

Django REST Framework

Django REST framework は、Django を基盤として Web API を構築するための柔軟なツールキットとして作成され、その API 機能が向上しました。

Mozilla、Red Hat、Eventbrite など、多くの企業で使用されています。

これは 自動 API ドキュメント の最初の例の 1 つであり、これが特に FastAPI の「探求」をインスピレーションした最初のアイデアの 1 つでした。

ノート

Django REST Framework は Tom Christie によって作成されました。彼は、FastAPI の基盤となっている Starlette と Uvicorn の作成者でもあります。

FastAPI にインスピレーションを与えたのは

自動APIドキュメントWebユーザーインターフェースを持つ。

Flask

Flask は「マイクロフレームワーク」であり、データベース統合や Django にデフォルトで含まれる多くのものは含まれていません。

このシンプルさと柔軟性により、NoSQL データベースを主要なデータストレージシステムとして使用するなどのことが可能です。

非常にシンプルであるため、比較的直感的に学習できますが、ドキュメントは一部の点でやや技術的になります。

また、データベース、ユーザー管理、または Django に組み込まれている多くの機能のいずれも必ずしも必要としない他のアプリケーションにも一般的に使用されます。これらの機能の多くはプラグインで追加できます。

この部分の分離、および必要なものを正確にカバーするために拡張できる「マイクロフレームワーク」であることは、私が維持したかった重要な機能でした。

Flask のシンプルさを考えると、API 構築に適しているように思えました。次に探すべきは、Flask 用の「Django REST Framework」でした。

FastAPI にインスピレーションを与えたのは

マイクロフレームワークであること。必要なツールとパーツを簡単に組み合わせて使えるようにする。

シンプルで使いやすいルーティングシステムを持つ。

Requests

FastAPI は実際には Requests の代替ではありません。その範囲は非常に異なります。

実際には、FastAPI アプリケーションの 内部 で Requests を使用するのが一般的でしょう。

しかし、それでも FastAPI は Requests から多くのインスピレーションを得ました。

Requests は API を (クライアントとして) 操作する ライブラリであり、FastAPI は API を (サーバーとして) 構築する ライブラリです。

それらは、多かれ少なかれ、反対の端に位置し、互いに補完し合っています。

Requests は非常にシンプルで直感的なデザインで、使いやすく、適切なデフォルト設定がされています。しかし同時に、非常に強力でカスタマイズ可能です。

そのため、公式サイトに記載されているように

Requests は史上最もダウンロードされた Python パッケージの 1 つです

使い方はとても簡単です。例えば、GET リクエストを行うには、次のように書きます。

response = requests.get("http://example.com/some/url")

FastAPI の対応する API パス操作 は次のようになります。

@app.get("/some/url")
def read_url():
    return {"message": "Hello World"}

requests.get(...)@app.get(...) の類似点をご覧ください。

FastAPI にインスピレーションを与えたのは

  • シンプルで直感的なAPIを持つ。
  • HTTPメソッド名(操作)を直接、分かりやすく直感的な方法で使用する。
  • 妥当なデフォルト値を持つが、強力なカスタマイズ性も備える。

Swagger / OpenAPI

Django REST Frameworkから欲しかった主な機能は、自動APIドキュメントでした。

その後、Swaggerと呼ばれるJSON(またはJSONの拡張であるYAML)を使用してAPIを文書化するための標準があることを知りました。

そして、Swagger API用のWebユーザーインターフェースはすでに作成されていました。したがって、APIのSwaggerドキュメントを生成できれば、このWebユーザーインターフェースを自動的に使用できることになります。

ある時点で、Swagger は Linux Foundation に寄付され、OpenAPI と改名されました。

そのため、バージョン2.0については「Swagger」、バージョン3以降については「OpenAPI」と言うのが一般的です。

FastAPI にインスピレーションを与えたのは

カスタムスキーマではなく、API 仕様のためのオープン スタンダードを採用し、使用する。

そして、標準ベースのユーザーインターフェースツールを統合する

この2つは非常に人気があり安定しているため選ばれましたが、少し検索するだけで、OpenAPIの代替ユーザーインターフェースが数十個見つかります(これらはFastAPIで使用できます)。

Flask REST frameworks

いくつかの Flask REST フレームワークがありますが、それらを調査するために時間と労力を費やした結果、多くが廃止または放棄されており、いくつかの未解決の問題がそれらを使用できないものにしていることがわかりました。

Marshmallow

API システムが必要とする主要な機能の 1 つは、データ「シリアル化」です。これは、コード (Python) からデータを取り出し、ネットワーク経由で送信できる形式に変換することです。たとえば、データベースからのデータを含むオブジェクトを JSON オブジェクトに変換したり、datetime オブジェクトを文字列に変換したりします。

APIが必要とするもう1つの大きな機能は、データ検証です。これは、特定のパラメータが与えられたときにデータが有効であることを確認することです。たとえば、あるフィールドがintであり、ランダムな文字列ではないことを確認します。これは、受信データにとって特に便利です。

データ検証システムがなければ、すべてのチェックを手動でコードで行う必要があります。

これらの機能は、Marshmallow が提供するために構築されたものです。これは素晴らしいライブラリで、以前にもたくさん使っていました。

しかし、これはPythonの型ヒントが存在する前に作成されました。そのため、すべてのスキーマを定義するには、Marshmallowが提供する特定のユーティリティとクラスを使用する必要があります。

FastAPI にインスピレーションを与えたのは

データ型と検証を提供する「スキーマ」を自動的に定義するためにコードを使用する。

Webargs

API に必要なもう 1 つの大きな機能は、受信リクエストからのデータの 解析 です。

Webargs は、Flask を含むいくつかのフレームワーク上でそれを提供するために作られたツールです。

データの検証には Marshmallow を内部で使用しています。そして、同じ開発者によって作成されました。

それは素晴らしいツールであり、FastAPI を持つ前もたくさん使っていました。

情報

Webargs は Marshmallow の同じ開発者によって作成されました。

FastAPI にインスピレーションを与えたのは

受信リクエストデータの自動検証を行う。

APISpec

Marshmallow と Webargs は、検証、解析、シリアル化をプラグインとして提供します。

しかし、ドキュメントはまだ不足しています。そこで APISpec が作成されました。

これは多くのフレームワーク用のプラグインです(Starlette用にもプラグインがあります)。

その仕組みは、各ルートを処理する関数のドキュメント文字列内にYAML形式でスキーマの定義を記述することです。

そして、OpenAPI スキーマを生成します。

Flask、Starlette、Responder などではこのように動作します。

しかし、またしても Python の文字列 (大きな YAML) の中にマイクロ構文があるという問題が発生します。

エディタはそれほど助けてくれません。そして、パラメータや Marshmallow スキーマを変更し、その YAML ドキュメント文字列も変更し忘れると、生成されたスキーマは古くなってしまいます。

情報

APISpec は Marshmallow の同じ開発者によって作成されました。

FastAPI にインスピレーションを与えたのは

API のオープン標準である OpenAPI をサポートする。

Flask-apispec

Webargs、Marshmallow、APISpec を連携させる Flask プラグインです。

Webargs と Marshmallow からの情報を利用して、APISpec を使って OpenAPI スキーマを自動的に生成します。

これは素晴らしいツールで、非常に過小評価されています。多くのFlaskプラグインよりもはるかに人気があるはずです。ドキュメントが簡潔で抽象的すぎるのが原因かもしれません。

これにより、Pythonのドキュメント文字列の中にYAML(別の構文)を記述する必要がなくなりました。

Flask、Flask-apispec、Marshmallow、Webargs の組み合わせは、FastAPI を構築するまで私のお気に入りのバックエンドスタックでした。

これを使用することで、いくつかの Flask フルスタックジェネレータが作成されました。これらは、私(およびいくつかの外部チーム)がこれまで使用してきた主要なスタックです。

そして、これらの同じフルスタックジェネレータがFastAPIプロジェクトジェネレータの基盤となりました。

情報

Flask-apispec は Marshmallow の同じ開発者によって作成されました。

FastAPI にインスピレーションを与えたのは

シリアル化と検証を定義する同じコードから、OpenAPI スキーマを自動的に生成する。

NestJS (と Angular)

これは Python ですらありません。NestJS は Angular にインスパイアされた JavaScript (TypeScript) の NodeJS フレームワークです。

Flask-apispec でできることと似たようなことを実現しています。

Angular 2 に触発された統合された依存性注入システムを備えています。「注入可能」なもの(私が知っている他のすべての依存性注入システムと同様に)を事前登録する必要があるため、冗長性とコードの重複が増します。

パラメータはTypeScriptの型(Pythonの型ヒントに似ています)で記述されているため、エディタのサポートはかなり良好です。

しかし、TypeScript のデータは JavaScript へのコンパイル後に保持されないため、型に依存して検証、シリアル化、ドキュメントを同時に定義することはできません。このことといくつかの設計上の決定により、検証、シリアル化、自動スキーマ生成を得るには、多くの場所にデコレータを追加する必要があります。そのため、かなり冗長になります。

ネストされたモデルをうまく処理できません。したがって、リクエストの JSON ボディが、さらにネストされた JSON オブジェクトである内部フィールドを持つ JSON オブジェクトである場合、適切にドキュメント化および検証できません。

FastAPI にインスピレーションを与えたのは

Python の型を使用して優れたエディタサポートを実現する。

強力な依存性注入システムを持つ。コードの重複を最小限に抑える方法を見つける。

Sanic

それは asyncio に基づく最初の非常に高速なPythonフレームワークの1つでした。Flaskに非常に似ているように作られました。

技術的な詳細

デフォルトのPython asyncio ループの代わりにuvloopを使用していました。それがそれを非常に高速にしました。

それは明らかにUvicornとStarletteにインスピレーションを与え、これらは現在オープンベンチマークでSanicよりも高速です。

FastAPI にインスピレーションを与えたのは

驚異的なパフォーマンスを得る方法を見つける。

そのため、FastAPI は Starlette をベースにしています。Starlette は(サードパーティのベンチマークによってテストされた)最速のフレームワークだからです。

Falcon

Falcon は別の高性能 Python フレームワークで、最小限に設計されており、Hug のような他のフレームワークの基盤として機能します。

これは、1 つの「リクエスト」と 1 つの「レスポンス」の 2 つのパラメーターを受け取る関数を持つように設計されています。その後、リクエストから一部を「読み取り」、レスポンスに一部を「書き込み」ます。この設計のため、標準の Python 型ヒントを関数パラメーターとして使用してリクエストパラメーターとボディを宣言することはできません。

そのため、データ検証、シリアル化、およびドキュメントは、自動的にではなく、コードで実行する必要があります。あるいは、Hug のように Falcon の上にフレームワークとして実装する必要があります。この同じ区別は、リクエストオブジェクトとレスポンスオブジェクトをパラメーターとして持つという Falcon の設計に触発された他のフレームワークでも発生します。

FastAPI にインスピレーションを与えたのは

優れたパフォーマンスを得る方法を見つける。

Hug (Hug は Falcon をベースにしているため) とともに、FastAPI に関数で response パラメーターを宣言することをインスピレーションを与えました。

ただし、FastAPI ではオプションであり、主にヘッダー、クッキー、および代替ステータスコードを設定するために使用されます。

Molten

Molten は、FastAPI の構築の初期段階で発見しました。そして、それは非常に似たアイデアを持っています。

  • Python の型ヒントに基づいています。
  • これらの型からの検証とドキュメント。
  • 依存性注入システム。

Pydantic のようなサードパーティのデータ検証、シリアル化、ドキュメント作成ライブラリを使用せず、独自のライブラリを使用しています。したがって、これらのデータ型定義は簡単に再利用できません。

少し冗長な設定が必要です。また、WSGI (ASGI ではなく) に基づいているため、Uvicorn、Starlette、Sanic のようなツールが提供する高性能を利用するようには設計されていません。

依存性注入システムは、依存性の事前登録を必要とし、依存性は宣言された型に基づいて解決されます。そのため、特定の型を提供する複数の「コンポーネント」を宣言することはできません。

ルートは、他の場所で宣言された関数を使用して(エンドポイントを処理する関数のすぐ上に配置できるデコレータを使用する代わりに)、1か所で宣言されます。これは、Flask(およびStarlette)のやり方よりもDjangoのやり方に近く、比較的密接に結合しているものをコード内で分離します。

FastAPI にインスピレーションを与えたのは

モデル属性の「デフォルト」値を使用して、データ型の追加検証を定義する。これによりエディタのサポートが向上し、以前はPydanticでは利用できませんでした。

これは実際にPydanticの一部を更新するきっかけとなり、同じ検証宣言スタイルをサポートするようになりました(この機能はすべてPydanticで既に利用可能です)。

Hug

Hug は、Python の型ヒントを使用して API パラメーターの型を宣言する最初のフレームワークの 1 つでした。これは、他のツールも同様に行うように促した素晴らしいアイデアでした。

宣言に標準の Python 型ではなくカスタム型を使用していましたが、それでも大きな前進でした。

また、API全体をJSONで宣言するカスタムスキーマを生成する最初のフレームワークの1つでもありました。

OpenAPI や JSON Schema のような標準に基づいていなかったため、Swagger UI のような他のツールとの統合は簡単ではありませんでした。しかし、それでも非常に革新的なアイデアでした。

興味深い、珍しい機能として、同じフレームワークを使用して API と CLI の両方を作成できます。

これは、同期 Python Web フレームワーク (WSGI) の以前の標準に基づいているため、Websocket やその他のものを処理することはできませんが、それでも高いパフォーマンスを発揮します。

情報

Hug は Timothy Crosley によって作成されました。彼は Python ファイル内のインポートを自動的にソートする素晴らしいツールである isort の作成者でもあります。

FastAPI にインスピレーションを与えたアイデア

Hug は APIStar の一部にインスピレーションを与え、APIStar と並んで最も有望だと感じたツールの 1 つでした。

Hug は、FastAPI が Python の型ヒントを使ってパラメータを宣言し、API を定義するスキーマを自動的に生成するのに貢献しました。

Hug は、ヘッダーとクッキーを設定するために、関数で response パラメーターを宣言することを FastAPI にインスピレーションを与えました。

APIStar (<= 0.5)

FastAPI の構築を決める直前に、APIStar サーバーを見つけました。私が探していたほとんどすべてがあり、素晴らしいデザインでした。

私が今まで見た中で、Python の型ヒントを使用してパラメーターとリクエストを宣言するフレームワークの最初の実装の 1 つでした (NestJS や Molten の前)。Hug とほぼ同時期に発見しました。しかし、APIStar は OpenAPI 標準を使用していました。

複数の箇所で同じ型ヒントに基づいて、自動データ検証、データシリアル化、および OpenAPI スキーマ生成が行われました。

ボディスキーマの定義はPydanticのようなPythonの型ヒントを使用せず、Marshmallowに少し似ていたため、エディタのサポートはそれほど良くありませんでしたが、それでもAPIStarは利用可能な最良の選択肢でした。

当時のベンチマークで最高のパフォーマンスを発揮していました(Starletteにのみ劣る)。

当初、自動 API ドキュメントの Web UI はありませんでしたが、Swagger UI を追加できることは知っていました。

依存性注入システムがありました。前述の他のツールと同様に、コンポーネントの事前登録が必要でした。しかし、それでも素晴らしい機能でした。

セキュリティ統合がなかったため、完全なプロジェクトで使用することはできませんでした。そのため、Flask-apispec に基づくフルスタックジェネレータで利用していたすべての機能を置き換えることはできませんでした。その機能を追加するプルリクエストを作成することがプロジェクトのバックログにありました。

しかし、その後、プロジェクトの焦点がシフトしました。

作成者がStarletteに集中する必要があったため、もはやAPI Webフレームワークではありませんでした。

現在、APIStar は Web フレームワークではなく、OpenAPI 仕様を検証するための一連のツールです。

情報

APIStar は Tom Christie によって作成されました。彼は以下の作成者でもあります。

  • Django REST Framework
  • Starlette (FastAPI のベース)
  • Uvicorn (Starlette および FastAPI で使用)

FastAPI にインスピレーションを与えたのは

存在する。

同じPython型で複数のもの(データ検証、シリアル化、ドキュメント)を宣言し、同時に優れたエディタサポートを提供するというアイデアは、素晴らしいアイデアだと考えました。

そして、長い間似たようなフレームワークを探し、多くの異なる代替案を試した結果、APIStarが最良の選択肢でした。

その後、APIStar はサーバーとしての存在を終え、Starlette が作成され、そのようなシステムのより良い新しい基盤となりました。それが FastAPI を構築する最終的なインスピレーションとなりました。

FastAPI は、APIStar の「精神的な後継者」であると考えています。これまでのすべてのツールから学んだことを基に、機能、型付けシステム、その他の部分を改善し、向上させています。

FastAPI で使用されています

Pydantic

Pydantic は、Python の型ヒントに基づいてデータ検証、シリアル化、およびドキュメント (JSON Schema を使用) を定義するためのライブラリです。

これにより、非常に直感的になります。

Marshmallow と比較できます。ただし、ベンチマークでは Marshmallow よりも高速です。そして、同じ Python の型ヒントに基づいているため、エディタのサポートは素晴らしいです。

FastAPI はそれを次の目的で使用します。

すべてのデータ検証、データシリアル化、および自動モデルドキュメント(JSON Schemaに基づく)を処理します。

FastAPI は、その JSON スキーマ データを取り込み、OpenAPI に配置します。その他にも様々なことを行います。

Starlette

Starlette は軽量な ASGI フレームワーク/ツールキットで、高性能な asyncio サービスを構築するのに理想的です。

非常にシンプルで直感的です。簡単に拡張でき、モジュール式のコンポーネントを持つように設計されています。

それは

  • 非常に印象的なパフォーマンス。
  • WebSocketサポート。
  • プロセス内バックグラウンドタスク。
  • 起動・終了イベント。
  • HTTPXをベースにしたテストクライアント。
  • CORS、GZip、静的ファイル、ストリーミング応答。
  • セッションとクッキーのサポート。
  • 100% のテストカバレッジ。
  • 100% 型アノテーションされたコードベース。
  • ハードな依存関係がほとんどない。

Starlette は現在、テスト済みの Python フレームワークの中で最速です。フレームワークではなくサーバーである Uvicorn にのみ劣ります。

Starlette はすべての基本的な Web マイクロフレームワーク機能を提供します。

ただし、自動データ検証、シリアル化、またはドキュメントは提供しません。

それが FastAPI が上に加える主なものの1つです。すべて Python の型ヒント(Pydantic を使用)に基づいています。それに加えて、依存性注入システム、セキュリティユーティリティ、OpenAPI スキーマ生成などが含まれます。

技術的な詳細

ASGI は、Django コアチームのメンバーによって開発されている新しい「標準」です。まだ「Python 標準」(PEP)ではありませんが、その過程にあります。

それにもかかわらず、すでにいくつかのツールで「標準」として使用されています。これにより、Uvicorn を他の ASGI サーバー (Daphne や Hypercorn など) に切り替えたり、python-socketio のような ASGI 互換ツールを追加したりできるため、相互運用性が大幅に向上します。

FastAPI はそれを次の目的で使用します。

すべてのコアウェブ部分を処理する。機能を追加する。

FastAPI クラス自体は、Starlette クラスから直接継承しています。

したがって、Starlette でできることはすべて、FastAPI で直接行うことができます。基本的には「強化された」Starlette だからです。

Uvicorn

Uvicorn は uvloop と httptools 上に構築された、超高速の ASGI サーバーです。

それはウェブフレームワークではなく、サーバーです。例えば、パスによるルーティングのためのツールは提供しません。それは Starlette(または FastAPI)のようなフレームワークが上に提供するものです。

Starlette および FastAPI の推奨サーバーです。

FastAPI はそれを次のように推奨しています。

FastAPI アプリケーションを実行するための主要なウェブサーバー。

--workers コマンドラインオプションを使用して、非同期マルチプロセスサーバーを持つこともできます。

詳細については、デプロイセクションを参照してください。

ベンチマークと速度

Uvicorn、Starlette、FastAPI の違いを理解し、比較するには、ベンチマークのセクションをご覧ください。