FastAPI에서 Pydantic 모델 재사용 시 주의할 점

문제 상황

사용자 정보 API를 만들면서 생성(POST)과 응답(GET)에 같은 Pydantic 모델을 사용했다. 처음엔 편해 보였지만, 요구사항이 변경되면서 문제가 생겼다.

class User(BaseModel):
    email: str
    password: str
    name: str
    created_at: datetime

생성 시에는 created_at이 필요 없고, 응답 시에는 password를 제외해야 했다. 그런데 모델을 공유하다 보니 불필요한 필드가 계속 노출됐다.

해결 방법

결국 용도별로 모델을 분리했다.

class UserBase(BaseModel):
    email: str
    name: str

class UserCreate(UserBase):
    password: str

class UserResponse(UserBase):
    id: int
    created_at: datetime
    
    class Config:
        orm_mode = True

공통 필드는 UserBase에 두고, 생성/응답용 모델을 분리했다. FastAPI 공식 문서에서도 권장하는 방식이었다.

추가 개선

업데이트(PATCH) API를 위해 모든 필드가 optional인 모델도 필요했다.

class UserUpdate(BaseModel):
    email: Optional[str] = None
    name: Optional[str] = None
    password: Optional[str] = None

처음엔 중복 코드가 많아 보였지만, 각 API의 요구사항이 명확해지면서 유지보수가 훨씬 쉬워졌다. 타입 안정성도 확보됐다.

초반에 모델 하나로 통일하려다 나중에 리팩토링 비용이 더 컸다. 처음부터 용도별로 분리하는 게 정답이었다.

FastAPI에서 Pydantic 모델 재사용 시 주의할 점