跳至內容

額外狀態碼

預設情況下,FastAPI 會使用 JSONResponse 返回回應,將您從路徑操作返回的內容放入該 JSONResponse 中。

它會使用預設狀態碼或您在路徑操作中設定的狀態碼。

額外狀態碼

如果您除了主要狀態碼之外还想返回其他狀態碼,您可以直接返回一個 Response,例如 JSONResponse,並直接設定額外的狀態碼。

例如,假設您想要一個允許更新項目的路徑操作,並在成功時返回 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)

警告

當您直接返回一個 Response 時,就像上面的例子一樣,它會被直接返回。

它不會使用模型等進行序列化。

請確保它包含您想要的數據,並且這些值是有效的 JSON(如果您使用的是 JSONResponse)。

「技術細節」

您也可以使用 from starlette.responses import JSONResponse

FastAPI 提供與 starlette.responses 相同的 fastapi.responses,只是為了方便您,開發人員。但大多數可用的回應都直接來自 Starlette。status 也是如此。

OpenAPI 和 API 文件

如果您直接返回額外的狀態碼和回應,它們將不會包含在 OpenAPI 模式(API 文件)中,因為 FastAPI 無法事先知道您將返回什麼。

但您可以在程式碼中使用以下方法記錄:額外回應