응답을 직접 반환하기¶
FastAPI에서 경로 처리(path operation)를 생성할 때, 일반적으로 dict, list, Pydantic 모델, 데이터베이스 모델 등의 데이터를 반환할 수 있습니다.
기본적으로 FastAPI는 JSON 호환 가능 인코더에 설명된 jsonable_encoder를 사용해 해당 반환 값을 자동으로 JSON으로 변환합니다.
그런 다음, 내부적으로는 JSON 호환 데이터(예: dict)를 JSONResponse에 넣어 클라이언트로 응답을 전송하는 데 사용합니다.
하지만 경로 처리에서 JSONResponse를 직접 반환할 수도 있습니다.
예를 들어, 사용자 정의 헤더나 쿠키를 반환해야 하는 경우에 유용할 수 있습니다.
Response 반환하기¶
사실, Response 또는 그 하위 클래스를 반환할 수 있습니다.
팁
JSONResponse 자체도 Response의 하위 클래스입니다.
그리고 Response를 반환하면 FastAPI가 이를 그대로 전달합니다.
Pydantic 모델로 데이터 변환을 수행하지 않으며, 내용을 다른 형식으로 변환하지 않습니다.
이로 인해 많은 유연성을 얻을 수 있습니다. 어떤 데이터 유형이든 반환할 수 있고, 데이터 선언이나 유효성 검사를 재정의할 수 있습니다.
Response에서 jsonable_encoder 사용하기¶
FastAPI는 반환하는 Response에 아무런 변경도 하지 않으므로, 그 내용이 준비되어 있는지 확인해야 합니다.
예를 들어, Pydantic 모델을 먼저 dict로 변환하고 datetime, UUID 등의 모든 데이터 타입을 JSON 호환 타입으로 변환하지 않으면 Pydantic 모델을 JSONResponse에 넣을 수 없습니다.
이러한 경우, 데이터를 응답에 전달하기 전에 jsonable_encoder를 사용하여 변환할 수 있습니다:
from datetime import datetime
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: 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)
🤓 Other versions and variants
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는 개발자의 편의를 위해 starlette.responses를 fastapi.responses로 제공합니다. 하지만 대부분의 사용 가능한 응답은 Starlette에서 직접 제공합니다.
사용자 정의 Response 반환하기¶
위 예제는 필요한 모든 부분을 보여주지만, 아직은 그다지 유용하지 않습니다. item을 그냥 직접 반환했어도 FastAPI가 기본으로 이를 JSONResponse에 넣고 dict로 변환하는 등의 작업을 모두 수행해 주었을 것이기 때문입니다.
이제, 이를 사용해 사용자 정의 응답을 반환하는 방법을 알아보겠습니다.
예를 들어 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를 직접 반환할 때, 그 데이터는 자동으로 유효성 검사되거나, 변환(직렬화)되거나, 문서화되지 않습니다.
그러나 OpenAPI에서 추가 응답에서 설명된 대로 문서화할 수 있습니다.
이후 섹션에서 자동 데이터 변환, 문서화 등을 계속 사용하면서 이러한 사용자 정의 Response를 사용하는/선언하는 방법을 확인할 수 있습니다.