はじめに
-
FastAPI
をインポート -
app
インスタンスを生成 - パスオペレーションデコレータを記述 (
@app.get("/")
) - パスオペレーション関数を定義 (上記の
def root(): ...
のように) - 開発サーバーを起動 (
uvicorn main:app --reload
)
型チェック
Pythonの型宣言を使用することで、FastAPIは以下を行います:
- エディターサポート: エラーチェック、自動補完、など
- データ「解析」
- データバリデーション
- APIアノテーションと自動ドキュメント生成
Pydantic
BaseModel
が使われる場面
-
APIリクエストやレスポンスのデータ構造化
FastAPIやDjangoなどで、クライアントとのデータやり取りをモデル化。
→ 入ってくるデータに対してチェックを行う
-
設定管理
アプリケーションの設定を定義し、環境変数や設定ファイルからのデータ読み込みに利用。
-
データの型安全性
Pythonの型ヒントと組み合わせることで、コードの可読性と安全性が向上。
BaseModel
を継承したクラスに属性を設定する。そして、Pythonの型をそれぞれに当てはめる。(Union)
リクエストボディ
そのPythonの型宣言だけで FastAPI は以下のことを行います:
- リクエストボディをJSONとして読み取ります。
- 適当な型に変換します(必要な場合)。
- データを検証します。(
Pydentic
のBaseModel
)- データが無効な場合は、明確なエラーが返され、どこが不正なデータであったかを示します。
- 受け取ったデータをパラメータ
item
に変換します。- 関数内で
Item
型であると宣言したので、すべての属性とその型に対するエディタサポート(補完など)をすべて使用できます。
- 関数内で
- モデルのJSONスキーマ定義を生成し、好きな場所で使用することができます。
- これらのスキーマは、生成されたOpenAPIスキーマの一部となり、自動ドキュメントのUIに使用されます。
URLについて
クエリパラメータ
基本
クエリパラメータは、URLの末尾に?
で始まり、その後にキー=値
の形式で指定します。複数のパラメータを使用する場合は、&
で区切ります。
使用例
- 検索条件付きのAPIリクエスト
GET /users?age=25&country=Japan
- 意味: 25歳で日本在住のユーザーを取得。
- ページネーションとフィルタリング
GET /products?page=3&limit=10&category=books
- 意味:
- 3ページ目のデータを取得。
- 1ページあたり10件。
- カテゴリは「本」。
- グラフ表示の設定
GET /chart?start_date=2024-01-01&end_date=2024-01-31&type=line
- 意味:
- 2024年1月1日から31日までの期間。
- 折れ線グラフ(line)を指定。
FastAPIの場合
from typing import Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
例)
1. クエリパラメータなしのリクエスト
GET /items/
-
クエリパラメータが渡されない場合、
q
はNone
になります。 -
レスポンス:
{ "items": [ {"item_id": "Foo"}, {"item_id": "Bar"} ] }
2. クエリパラメータありのリクエスト
GET /items/?q=FastAPI
-
クエリパラメータ
q=FastAPI
が指定されています。 -
レスポンス:
{ "items": [ {"item_id": "Foo"}, {"item_id": "Bar"} ], "q": "FastAPI" }
パスパラメータ
基本
http(s)://<ベースURL>/<固定部分>/<パスパラメータ>/<固定部分>...
-
ベースURL:
APIのエンドポイントの基本部分(例:
https://example.com
) -
固定部分:
動的でないURLの部分(例:
/users
) -
パスパラメータ:
{}
(波括弧)で囲まれた部分。リソースに応じて動的に値が変更されます(例:{user_id}
)
使用例
GET /users/{user_id}
-
user_id
は動的な値(例: 123, 456)に置き換わります。 - 実際のリクエスト例:
-
/users/123
→ ユーザーIDが123
の情報を取得。 -
/users/456
→ ユーザーIDが456
の情報を取得。
-
FastAPIの場合
from typing import Union
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get"),
q: Union[str, None] = Query(default=None, alias="item-query"),
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
非同期処理
待つ必要がない処理に対してasync
を宣言する。
具体的には以下のような処理
- APIリクエスト / レスポンス
- ネットワーク経由でクライアントから送信されるデータ
- ネットワーク経由でクライアントが受信する、プログラムから送信されたデータ
- リモートAPI操作
- データ読み込み
- システムによって読み取られ、プログラムに渡されるディスク内のファイル内容
- プログラムがシステムに渡して、ディスクに書き込む内容
- DB操作
- データベース操作の完了
- データベースクエリが結果を返すこと
APIの実装
APIの動作確認(OpenAPI)
localhost:8000/docsから自動生成ドキュメント画面を開ける
通常、APIの動作確認にはcurlコマンドを実行してリクエストに対するレスポンスが正しく返されているか確認するが、FastAPIではブラウザ上から確認できる。
また、「エンドポイント」と「関数」のペアが画面上で確認でき、API仕様が一目で確認できる。これは、ユーザーのアクションに応じてどんな画面が表示されるか可視化するのに有効である。
CRUD操作
CRUD操作はHTTPメソッドにそれぞれ対応している。
(例:POST→Create、GET→Read)