クエリパラメータ¶
パスパラメータではない関数パラメータを宣言すると、それらは自動的に "クエリ" パラメータとして解釈されます。
from fastapi import FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip : skip + limit]
クエリはURL内で ?
の後に続くキーとバリューの組で、 &
で区切られています。
例えば、以下の様なURL内で:
http://127.0.0.1:8000/items/?skip=0&limit=10
...クエリパラメータは:
skip
: 値は0
limit
: 値は10
これらはURLの一部なので、「自然に」文字列になります。
しかしPythonの型を宣言すると (上記の例では int
として)、その型に変換されバリデーションが行われます。
パスパラメータに適用される処理と完全に同様な処理がクエリパラメータにも施されます:
- エディターサポート (明らかに)
- データ「解析」
- データバリデーション
- 自動ドキュメント生成
デフォルト¶
クエリパラメータはパスの固定部分ではないので、オプショナルとしたり、デフォルト値をもつことができます。
上述の例では、skip=0
と limit=10
というデフォルト値を持っています。
したがって、以下のURLにアクセスすることは:
http://127.0.0.1:8000/items/
以下のURLにアクセスすることと同等になります:
http://127.0.0.1:8000/items/?skip=0&limit=10
しかし、例えば、以下にアクセスすると:
http://127.0.0.1:8000/items/?skip=20
関数内のパラメータの値は以下の様になります:
skip=20
: URL内にセットしたためlimit=10
: デフォルト値
オプショナルなパラメータ¶
同様に、デフォルト値を None
とすることで、オプショナルなクエリパラメータを宣言できます:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
この場合、関数パラメータ q
はオプショナルとなり、デフォルトでは None
になります。
確認
パスパラメータ item_id
はパスパラメータであり、q
はそれとは違ってクエリパラメータであると判別できるほどFastAPI が賢いということにも注意してください。
備考
FastAPIは、= None
があるおかげで、q
がオプショナルだとわかります。
Optional[str]
のOptional
はFastAPIでは使用されていません(FastAPIはstr
の部分のみ使用します)。しかし、Optional[str]
はエディタがコードのエラーを見つけるのを助けてくれます。
クエリパラメータの型変換¶
bool
型も宣言できます。これは以下の様に変換されます:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None, short: bool = False):
item = {"item_id": item_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
この場合、以下にアクセスすると:
http://127.0.0.1:8000/items/foo?short=1
もしくは、
http://127.0.0.1:8000/items/foo?short=True
もしくは、
http://127.0.0.1:8000/items/foo?short=true
もしくは、
http://127.0.0.1:8000/items/foo?short=on
もしくは、
http://127.0.0.1:8000/items/foo?short=yes
もしくは、他の大文字小文字のバリエーション (アッパーケース、最初の文字だけアッパーケース、など)で、関数は short
パラメータを True
な bool
値として扱います。それ以外は False
になります。
複数のパスパラメータとクエリパラメータ¶
複数のパスパラメータとクエリパラメータを同時に宣言できます。FastAPIは互いを区別できます。
そして特定の順序で宣言しなくてもよいです。
名前で判別されます:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
user_id: int, item_id: str, q: Union[str, None] = None, short: bool = False
):
item = {"item_id": item_id, "owner_id": user_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
必須のクエリパラメータ¶
パスパラメータ以外のパラメータ (今のところ、クエリパラメータのみ説明しました) のデフォルト値を宣言した場合、そのパラメータは必須ではなくなります。
特定の値を与えずにただオプショナルにしたい場合はデフォルト値を None
にして下さい。
しかしクエリパラメータを必須にしたい場合は、ただデフォルト値を宣言しなければよいです:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_user_item(item_id: str, needy: str):
item = {"item_id": item_id, "needy": needy}
return item
ここで、クエリパラメータ needy
は str
型の必須のクエリパラメータです
以下のURLをブラウザで開くと:
http://127.0.0.1:8000/items/foo-item
...必須のパラメータ needy
を加えなかったので、以下の様なエラーが表示されます:
{
"detail": [
{
"loc": [
"query",
"needy"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
needy
は必須のパラメータなので、URLにセットする必要があります:
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
...これはうまくいくでしょう:
{
"item_id": "foo-item",
"needy": "sooooneedy"
}
そして当然、あるパラメータを必須に、別のパラメータにデフォルト値を設定し、また別のパラメータをオプショナルにできます:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_user_item(
item_id: str, needy: str, skip: int = 0, limit: Union[int, None] = None
):
item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
return item
この場合、3つのクエリパラメータがあります。:
needy
、必須のstr
。skip
、デフォルト値を0
とするint
。limit
、オプショナルなint
。
豆知識
パスパラメータと同様に Enum
を使用できます。