FastAPI에서 Pydantic 모델 validation 커스터마이징
문제 상황
회원가입 API를 개발하면서 비밀번호 정책 검증이 필요했다. 최소 8자 이상, 대소문자/숫자/특수문자 포함 여부를 체크해야 했는데, Pydantic의 기본 validator로는 에러 메시지 커스터마이징이 제한적이었다.
validator 데코레이터 활용
from pydantic import BaseModel, validator
import re
class UserCreate(BaseModel):
email: str
password: str
@validator('password')
def validate_password(cls, v):
if len(v) < 8:
raise ValueError('비밀번호는 8자 이상이어야 합니다')
if not re.search(r'[A-Z]', v):
raise ValueError('대문자를 포함해야 합니다')
if not re.search(r'[a-z]', v):
raise ValueError('소문자를 포함해야 합니다')
if not re.search(r'[0-9]', v):
raise ValueError('숫자를 포함해야 합니다')
return v
root_validator로 필드 간 검증
비밀번호 확인 필드가 추가되면서 두 필드를 비교해야 하는 상황이 생겼다. root_validator를 사용하면 모든 필드에 접근할 수 있다.
from pydantic import root_validator
class UserCreate(BaseModel):
email: str
password: str
password_confirm: str
@root_validator
def verify_password_match(cls, values):
pw1 = values.get('password')
pw2 = values.get('password_confirm')
if pw1 != pw2:
raise ValueError('비밀번호가 일치하지 않습니다')
return values
정리
@validator: 단일 필드 검증, 값 변환에 적합@root_validator: 여러 필드 간 관계 검증에 사용pre=True옵션으로 타입 변환 전 검증 가능
FastAPI + Pydantic 조합은 API 개발 속도를 확실히 높여줬다. 타입 힌팅과 자동 문서화까지 제공되니 Flask보다 생산성이 좋았다.