コンテンツにスキップ

レスポンスを直接返す

FastAPIpath operation では、通常は任意のデータを返すことができます: 例えば、 dictlist、Pydanticモデル、データベースモデルなどです。

デフォルトでは、FastAPIJSON互換エンコーダ で説明されている jsonable_encoder により、返す値を自動的にJSONに変換します。

このとき背後では、JSON互換なデータ (例えばdict) を、クライアントへ送信されるレスポンスとして利用される JSONResponse の中に含めます。

しかし、path operation から JSONResponse を直接返すこともできます。

これは例えば、カスタムヘッダーやcookieを返すときに便利です。

Response を返す

実際は、Response やそのサブクラスを返すことができます。

豆知識

JSONResponse それ自体は、 Response のサブクラスです。

Response を返した場合は、FastAPI は直接それを返します。

それは、Pydanticモデルのデータ変換や、コンテンツを任意の型に変換したりなどはしません。

これは多くの柔軟性を提供します。任意のデータ型を返したり、任意のデータ宣言やバリデーションをオーバーライドできます。

jsonable_encoderResponse の中で使う

FastAPI はあなたが返す Response に対して何も変更を加えないので、コンテンツが準備できていることを保証しなければなりません。

例えば、Pydanticモデルを JSONResponse に含めるには、すべてのデータ型 (datetimeUUID など) をJSON互換の型に変換された dict に変換しなければなりません。

このようなケースでは、レスポンスにデータを含める前に jsonable_encoder を使ってデータを変換できます。

from datetime import datetime
from typing import Union

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel


class Item(BaseModel):
    title: str
    timestamp: datetime
    description: Union[str, None] = None


app = FastAPI()


@app.put("/items/{id}")
def update_item(id: str, item: Item):
    json_compatible_item_data = jsonable_encoder(item)
    return JSONResponse(content=json_compatible_item_data)

技術詳細

また、from starlette.responses import JSONResponse も利用できます。

FastAPI は開発者の利便性のために fastapi.responses という starlette.responses と同じものを提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接提供されます。

カスタム Response を返す

上記の例では必要な部分を全て示していますが、あまり便利ではありません。item を直接返すことができるし、FastAPI はそれを dict に変換して JSONResponse に含めてくれるなど。すべて、デフォルトの動作です。

では、これを使ってカスタムレスポンスをどう返すか見てみましょう。

XMLレスポンスを返したいとしましょう。

XMLを文字列にし、Response に含め、それを返します。

from fastapi import FastAPI, Response

app = FastAPI()


@app.get("/legacy/")
def get_legacy_data():
    data = """<?xml version="1.0"?>
    <shampoo>
    <Header>
        Apply shampoo here.
    </Header>
    <Body>
        You'll have to use soap here.
    </Body>
    </shampoo>
    """
    return Response(content=data, media_type="application/xml")

備考

Response を直接返す場合、バリデーションや、変換 (シリアライズ) や、自動ドキュメントは行われません。

しかし、Additional Responses in OpenAPIに記載されたようにドキュメントを書くこともできます。

後のセクションで、カスタム Response を使用・宣言しながら、自動的なデータ変換やドキュメンテーションを行う方法を説明します。