FastAPI 서버개발, pydantic 모델을 사용한 요청 바디 검증

FastAPI는 Python으로 웹 API를 구축할 때 매우 인기가 높은 프레임워크입니다. FastAPI의 가장 큰 장점 중 하나는 Pydantic을 이용한 데이터 검증입니다. Pydantic은 강력한 데이터 검증 및 설정 관리 도구로, Python의 타입 힌팅을 활용하여 데이터를 검증하고 직렬화하는 기능을 제공합니다.

1. FastAPI 소개

FastAPI는 빠른 API 구축을 목표로 설계된 Python 웹 프레임워크이며, 성능과 생산성을 모두 고려하여 만들어졌습니다. 성능적으로는 Node.js와 Go에 근접하며, 쉬운 사용성을 가지고 있어 API 개발을 빠르게 진행할 수 있습니다.

1.1 주요 특징

  • 빠른 성능: Starlette와 Pydantic을 기반으로 한 비동기 처리를 지원합니다.
  • 자동 문서화: OpenAPI와 JSON Schema를 기반으로 하는 자동화된 API 문서화를 지원합니다.
  • 타입 힌팅: Python 3.6 이상의 버전을 활용하여 코드 가독성을 높이고, 데이터 검증을 용이하게 합니다.

2. Pydantic을 사용한 요청 바디 검증

FastAPI에서 요청 바디를 검증하는 가장 흔한 방법은 Pydantic 모델을 사용하는 것입니다. Pydantic 모델은 Python 클래스처럼 정의되며, 클래스의 속성은 필드와 그에 대한 타입 힌트를 제공합니다. 이를 통해 API의 요청 데이터를 검증할 수 있습니다.

2.1 Pydantic 모델 정의

Pydantic 모델을 정의하는 기본 형식은 다음과 같습니다.


from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    email: str
    age: int

위 코드는 사용자의 정보를 담고 있는 User 모델을 정의합니다. 각 속성은 그에 해당하는 데이터 타입을 명시하고 있습니다. Pydantic은 이 모델을 기반으로 데이터의 유효성을 검사합니다.

2.2 FastAPI와 Pydantic 모델의 통합

FastAPI에서는 경로 운영체제의 매개변수로 Pydantic 모델을 바로 사용할 수 있습니다. 예를 들어, 클라이언트가 보낸 JSON 요청을 User 모델로 검증할 수 있습니다.


from fastapi import FastAPI

app = FastAPI()

@app.post("/users/")
async def create_user(user: User):
    return {"user_id": user.id, "name": user.name}

위 코드에서 /users/ 경로에 대한 POST 요청이 오면, FastAPI는 JSON 요청 본문을 User 모델 인스턴스로 변환하고 검증합니다. 데이터가 유효하면, 해당 데이터가 user 매개변수로 전달됩니다.

2.3 필드 검증

Pydantic은 필드 검증을 위한 여러 기능을 제공합니다. 예를 들어, 필드에 대한 제약조건이나 검증 로직을 추가할 수 있습니다.


from pydantic import EmailStr, conint

class User(BaseModel):
    id: conint(ge=1)  # 1 이상의 정수만 허용
    name: str
    email: EmailStr  # 유효한 이메일 형식
    age: conint(ge=0)  # 0 이상의 정수로 유효성 검사

여기서 conintEmailStr은 각각 정수 범위와 이메일 형식의 유효성을 검사합니다. 이런 제약조건을 통해 잘못된 입력을 사전에 차단할 수 있습니다.

3. 요청 바디 검증의 실제 예제

아래는 FastAPI와 Pydantic 모델을 사용하여 간단한 사용자 관리 API를 구현한 예입니다. 이 예제에서는 사용자의 정보를 생성하고, 조회하는 API를 구현합니다.


from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, conint
from typing import List

app = FastAPI()

class User(BaseModel):
    id: conint(ge=1)
    name: str
    email: EmailStr
    age: conint(ge=0)

# 메모리에 사용자 데이터를 저장할 리스트
users_db = []

@app.post("/users/")
async def create_user(user: User):
    users_db.append(user)
    return {"user_id": user.id, "name": user.name}

@app.get("/users/", response_model=List[User])
async def get_users():
    return users_db

이 API는 다음과 같은 기능을 제공합니다:

  • POST /users/: 새로운 사용자를 생성합니다. Pydantic 모델을 통해 요청 바디의 유효성을 검증합니다.
  • GET /users/: 현재 등록된 사용자 목록을 조회합니다. 저장된 사용자 데이터를 반환합니다.

3.1 API 테스트

FastAPI는 Swagger UI를 통해 API를 쉽게 테스트할 수 있는 기능을 제공합니다. 서버를 실행한 후 http://127.0.0.1:8000/docs에 접속하면, 시각적으로 API를 테스트할 수 있는 인터페이스가 제공됩니다.

uvicorn main:app --reload

위 명령어로 FastAPI 서버를 실행한 후, 브라우저에서 Swagger UI에 접속해보세요. API 엔드포인트를 클릭하고, 요청에 대한 데이터를 입력하여 테스트할 수 있습니다.

3.2 오류 처리

Pydantic은 모델 객체 생성 시 오류를 감지하고, 자동으로 HTTPException을 발생시킵니다. 예를 들어, 유효하지 않은 이메일 주소를 입력하면 FastAPI는 자동으로 422 Unprocessable Entity 상태 코드를 반환합니다.


@app.post("/users/")
async def create_user(user: User):
    if user.age < 18:
        raise HTTPException(status_code=400, detail="Must be at least 18.")
    users_db.append(user)
    return {"user_id": user.id, "name": user.name}

위의 예시는 사용자 나이가 18세 미만일 경우 에러를 발생시키는 예입니다. 이렇게 FastAPI와 Pydantic은 함께 사용자 정의 예외 처리를 간편하게 구현할 수 있습니다.

4. 결론

FastAPI는 Pydantic을 활용하여 요청 바디에 대한 검증을 쉽게 처리할 수 있는 강력한 프레임워크입니다. 데이터 타입, 제약 조건, 이메일 형식 검증 등 다양한 검증 기능을 제공하며, 이를 통해 API 개발 과정에서 발생할 수 있는 오류를 사전에 방지할 수 있습니다. FastAPI와 Pydantic을 활용하여 시의적절하게 API를 구축하는 연습을 진행한다면, 실제 프로젝트에 큰 도움이 될 것입니다.

이 글이 FastAPI와 Pydantic을 사용하는 데 도움이 되기를 바랍니다. Now, it’s your turn to dive in and start building!