[FastAPI] 요청과 응답
FastAPI는 내부적으로 Pydantic 모델을 사용해 데이터의 유형을 선언하고 데이터를 검증하며 데이터를 전달한다.
Pydantic은 Python의 데이터 파싱 라이브러리로, FastAPI에서는 JSON과 Python 객체간 데이터 변환, 데이터 전송 형식 검증에 사용된다.
스프링에서는 @Valid 애너테이션을 사용해서 객체를 검증했는데 FastAPI에서는 Pydantic이 비슷한 역할을 수행한다.
class SubjectListResponse(BaseModel):
selected_subject: str
subjects: list
@subject_router.get("/get-list", response_model=schemas.SubjectListResponse)
def fetch_subject_list():
res = {
"selected_subject": ["selected subject"],
"subjects" : "subject"
}
return res
반환 값에 대한 검증을 수행하는 예시이다.
response_model 파라미터는 엔드포인트가 SubjectListResponse 모델을 사용해서 응답 데이터 형태를 검증하고 JSON으로 직렬화해서 데이터를 반환함을 지정한다.
BaseModel을 상속받는 클래스는 Pydantic모델이 되고 유효성 검사, 데이터 변환, 문서화, 오류 관리 등 다양한 기능을 수행할 수 있다.
물론 반환 값 검증 말고 엔드포인트에 대한 데이터 전송에 대해서도 검증을 수행할 수 있다.
꼭 Pydantic 모델을 사용해야 하는건 아니고... 간단한 int나 str 하나만 전송받을 때는 Pydantic모델을 정의하지 않아도 된다.
복잡한 데이터 구조를 다룰 때 Pydantic을 사용하자.
엔드포인트에서 데이터를 전달받을 때는 크게 세 가지 방법을 사용한다.
1. Query Parameter
/items/?query1=query1 같은 형태로 데이터를 받는다.
@app.get("/items/")
def read_items(query: str = None):
return {"query": query}
None으로 설정해 쿼리 파라미터가 필수가 아니도록 설정했다. 기본값을 설정하거나 필수로 지정할 수 있다.
2. Path Parameter
/items/3 같은 형태로 데이터를 받는다.
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
Path Parameter는 필수 파라미터로 생략할 수 없다.
3. Body Parameter
class Item(BaseModel):
name: str
description: str
@app.post("/items/")
def create_item(item: Item):
return item
Item 모델의 인스턴스는 Body로 전달되고, 클라이언트는 JSON 형식으로 데이터를 보내야 한다.
Pydantic의 BaseModel을 상속받는 클래스 타입은 FastAPI가 Body Parameter로 인식하고, 함수 파라미터에 기본값을 할당하면 FastAPI는 Query Parameter로 인식하며 함수의 데코레이터 경로에 포함된 변수는 Path Parameter로 인식한다.
그럼에도 Body, Query, Path 등 함수를 명시적으로 사용할 수 있는데, 이런 함수를 명시적으로 사용하게 되면 파라미터에 대한 메타데이터를 설정하거나 유효성 검사에 대한 규칙을 추가할 수 있고 추가한 내용들을 API 문서에 즉각 반영할 수 있다.
FastAPI의 설계 원칙 중 하나는 최소한의 코드로 최대한의 효과를 내도록 하는 것이다.
타입 애너테이션으로 자동으로 수행되는 부분이 많지만, 필요에 따라서는 명시적 도구를 사용해 세밀하게 제어하자.
스프링에서는 Query Parameter는 @RequestParam, Path Parameter는 @PathVariable, Body Parameter는 @RequestBody 애너테이션으로 각각 애너테이션을 붙여서 처리한다.
FastAPI와 스프링의 설계 원칙을 비교하며 기억하자.
스프링에서는 Jackson 라이브러리로 자바 객체를 JSON으로 변환하듯, FastAPI에서는 클라이언트에게 데이터를 응답할 때 파이썬 객체를 그대로 반환하면 Pydantic 모델이 JSON 형식으로 변환해준다.
좀 더 자세하게 들어가면 반환된 객체가 dict, list, Pydantic의 BaseModel 을 상속받는 경우 Starlette에 의해 JSON으로 자동 변환된다.
텍스트, 이미지, 파일 등 JSON 대신 다른 형식으로 반환하고 싶은 경우 Response 객체를 직접 사용할 수 있다.
파일을 전송할 때는 FileResponse, HTML을 전송할 때는 HTMLResponse를 사용하는 등 특화된 Response 객체를 통해 일반 Response의 특정 케이스를 좀 더 편하게 다룰 수 있다.
이렇게 Response 클래스나 하위 클래스를 명시적으로 사용하면 응답을 세밀하게 컨트롤 할 수 있고, 테스트하기 쉬우며 API 문서를 자동으로 작성하는 등 여러 이점을 얻을 수 있다.
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/items/{item_id}", response_class=JSONResponse)
async def read_item(item_id: int):
return {"item_id": item_id, "name": "name"}
###############
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return JSONResponse(content={"item_id": item_id, "name": "Foo"})
response_class 를 사용하는 예시와 직접 JSONResponse 객체를 반환하는 예시이다.
response_class를 사용하면 반환된 데이터를 자동으로 해당 응답 클래스의 인스턴스로 변환하고, 직접 JSONResponse를 반환하면 응답에 추가적인 헤더를 설정하거나 HTTP 상태 코드를 제어할 수 있다.
자동 변환과 문서화 기능을 사용할 때는 response_class를, 구체적인 로직이 필요하다면 JSONResponse 방식을 사용하자.
'FastAPI > FastAPI' 카테고리의 다른 글
FastAPI에서의 동시성 처리 (0) | 2023.11.29 |
---|---|
[FastAPI] SQLAlchemy (0) | 2023.11.06 |
댓글
이 글 공유하기
다른 글
-
FastAPI에서의 동시성 처리
FastAPI에서의 동시성 처리
2023.11.29 -
[FastAPI] SQLAlchemy
[FastAPI] SQLAlchemy
2023.11.06