コンテンツへスキップ

追加のステータスコード

デフォルトでは、FastAPIJSONResponseを使用してレスポンスを返し、パス操作から返されるコンテンツをそのJSONResponse内に配置します。

デフォルトのステータスコード、またはパス操作で設定したステータスコードを使用します。

追加のステータスコード

メインのステータスコードとは別に、追加のステータスコードを返したい場合は、JSONResponseのようなResponseを直接返し、追加のステータスコードを直接設定することで実現できます。

例えば、アイテムを更新するパス操作があり、成功した場合はHTTPステータスコード200 "OK"を返すとします。

しかし、新しいアイテムも受け入れたいとします。そして、アイテムが以前に存在しなかった場合は、それらを作成し、HTTPステータスコード201 "Created"を返します。

これを実現するには、JSONResponseをインポートし、コンテンツを直接そこに返し、必要なstatus_codeを設定します。

from typing import Annotated

from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse

app = FastAPI()

items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}


@app.put("/items/{item_id}")
async def upsert_item(
    item_id: str,
    name: Annotated[str | None, Body()] = None,
    size: Annotated[int | None, Body()] = None,
):
    if item_id in items:
        item = items[item_id]
        item["name"] = name
        item["size"] = size
        return item
    else:
        item = {"name": name, "size": size}
        items[item_id] = item
        return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
🤓 その他のバージョンとバリアント
from typing import Annotated, Union

from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse

app = FastAPI()

items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}


@app.put("/items/{item_id}")
async def upsert_item(
    item_id: str,
    name: Annotated[Union[str, None], Body()] = None,
    size: Annotated[Union[int, None], Body()] = None,
):
    if item_id in items:
        item = items[item_id]
        item["name"] = name
        item["size"] = size
        return item
    else:
        item = {"name": name, "size": size}
        items[item_id] = item
        return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
from typing import Union

from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse
from typing_extensions import Annotated

app = FastAPI()

items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}


@app.put("/items/{item_id}")
async def upsert_item(
    item_id: str,
    name: Annotated[Union[str, None], Body()] = None,
    size: Annotated[Union[int, None], Body()] = None,
):
    if item_id in items:
        item = items[item_id]
        item["name"] = name
        item["size"] = size
        return item
    else:
        item = {"name": name, "size": size}
        items[item_id] = item
        return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)

ヒント

可能であれば`Annotated`バージョンを使用することをお勧めします。

from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse

app = FastAPI()

items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}


@app.put("/items/{item_id}")
async def upsert_item(
    item_id: str,
    name: str | None = Body(default=None),
    size: int | None = Body(default=None),
):
    if item_id in items:
        item = items[item_id]
        item["name"] = name
        item["size"] = size
        return item
    else:
        item = {"name": name, "size": size}
        items[item_id] = item
        return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)

ヒント

可能であれば`Annotated`バージョンを使用することをお勧めします。

from typing import Union

from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse

app = FastAPI()

items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}


@app.put("/items/{item_id}")
async def upsert_item(
    item_id: str,
    name: Union[str, None] = Body(default=None),
    size: Union[int, None] = Body(default=None),
):
    if item_id in items:
        item = items[item_id]
        item["name"] = name
        item["size"] = size
        return item
    else:
        item = {"name": name, "size": size}
        items[item_id] = item
        return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)

Warning

上記の例のように、Responseを直接返すと、それは直接返されます。

モデルなどでシリアライズされることはありません。

必要なデータが含まれており、値が有効なJSONであることを確認してください(JSONResponseを使用している場合)。

技術的な詳細

from starlette.responses import JSONResponseを使用することもできます。

FastAPIは、開発者にとっての利便性として、starlette.responsesと全く同じものをfastapi.responsesとして提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接来ています。statusも同様です。

OpenAPIとAPIドキュメント

追加のステータスコードとレスポンスを直接返した場合、それらはOpenAPIスキーマ(APIドキュメント)には含まれません。なぜなら、FastAPIは、あなたが何を返すかを事前に知る方法がないからです。

しかし、追加のレスポンスを使用して、コード内でそれを文書化することができます。