FastAPIではリクエストやレスポンスが適切な内容であるかをバリデーションすることができます。
response_model
は名前の通りレスポンスに関する機能で、レスポンスについてバリデーションが行えます。
response_modelの基本
response_model
は下記のコードのように、パスを定義するデコレーターに与えます。
この場合だと、レスポンスは文字列であると指定しています。
from fastapi import FastAPI
app = FastAPI()
@app.get('/', response_model=str)
def index():
return 'response test'
ちなみにresponse_model
で指定した型以外を返すと、Internal Server Errorが発生してしまいます。
from fastapi import FastAPI
app = FastAPI()
@app.get('/', response_model=str)
def index():
return 1
# /にアクセスすると
# "GET / HTTP/1.1" 500 Internal Server Error
# とログに出力される。
例としてstr
をresponse_model
に指定しましたが、多くの場合レスポンスは文字列だけでなく、もっと複雑なはずです。
そのような場合はpydanticやtypingを利用して、複雑な型を用意してやる必要があります。
pydanticはfastapiに付随してインストールされ、typingは標準ライブラリなので、別途インストールは行わなくてOKです。
例えば、コーヒーの情報を返すAPIを作りたいとすると、以下のように型を作成してresponse_model
に使用します。
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List
app = FastAPI()
class CoffeeInfo(BaseModel):
brand: str
country: str
gram: int
# コーヒーの情報を返す
@app.get('/', response_model=CoffeeInfo)
def coffee():
return {
'brand': 'blue mountain',
'country': 'jamaica',
'gram': 100
}
# コーヒーの情報を複数返す
@app.get('/multi-coffee', response_model=List[CoffeeInfo])
def multi_coffee():
coffee1 = {
'brand': 'blue mountain',
'country': 'jamaica',
'gram': 100
}
coffee2 = {
'brand': 'kona',
'country': 'america',
'gram': 250
}
return [coffee1, coffee2]
要素の切り捨てとデフォルト値
要素の切り捨て
response_model
に指定した型を満たしているが、余計な要素が追加されている場合はどうなるでしょうか?
下記のコードでは、price
とcurrency
が余計にreturnされていますが、エラーにはなりません。
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class CoffeeInfo(BaseModel):
brand: str
country: str
gram: int
# コーヒーの情報を返す
@app.get('/', response_model=CoffeeInfo)
def coffee():
return {
'brand': 'blue mountain',
'country': 'jamaica',
'gram': 100,
'price': 800,
'currency': 'yen'
}
では、実際のレスポンスはどうなっているのでしょうか?Swagger UIにアクセスして、レスポンスを確認してみます。

レスポンスにはprice
とcurrency
は存在していません。このように、response_model
に指定した型を満たしているが、余計な要素がある場合は切り捨てられるようです。
デフォルト値
余計な要素は切り捨てられるようですが、逆に一部が不足している場合にはどうなるでしょうか?
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class CoffeeInfo(BaseModel):
brand: str
country: str
gram: int
# コーヒーの情報を返す
@app.get('/', response_model=CoffeeInfo)
def coffee():
return {
'brand': 'blue mountain',
'country': 'jamaica'
}
上記のコードをSwagger UIで確認してみると、Internal Server Errorとなっていることがわかります。

では、不足している要素を補うにはどうすれば良いでしょうか?
これはデフォルト値を設定すること可能です。
デフォルト値は、下記のようにして設定することができます。
class CoffeeInfo(BaseModel):
brand: str
country: str
gram: int = 100
デフォルト値を設定して再度アクセスすると、このようにエラーにはならずにデフォルト値を使用したレスポンスが得られています。

response_model_includeとresponse_model_excludeについて
工事中
コメント