본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 09. 12:13

AI 엔지니어를 위한 FastAPI - 파트 4: API를 망가뜨리기 전에 잘못된 데이터를 차단하세요 (Pydantic 및 데이터 검증)

요약

FastAPI 애플리케이션에서 Pydantic을 사용하여 데이터 검증을 구현하는 방법을 다룹니다. 잘못된 데이터가 API 시스템에 유입되는 것을 방지하고 데이터 타입을 보장하는 원리를 설명합니다.

핵심 포인트

  • Pydantic을 활용한 데이터 타입 검증의 중요성
  • 잘못된 데이터 유입 방지를 통한 API 안정성 확보
  • FastAPI와 Pydantic의 연동 원리 이해

이전 기사에서는 SQLite와 SQLAlchemy를 사용하여 FastAPI 애플리케이션을 데이터베이스에 연결했습니다.

또한 다음과 같은 클래스들을 사용했습니다:

class StudentCreate(BaseModel):
    name: str
    department: str
...

하지만 내부적으로 어떤 일이 일어나고 있는지는 완전히 이해하지 못한 채 사용했습니다.

오늘은 그 부분을 해결해 보겠습니다.

아직 읽지 않으셨다면 확인해 보세요:

AI 엔지니어를 위한 FastAPI - 파트 3: 데이터베이스 연결하기

zeroshotanu profile

Ananya S

Ananya S

Ananya S

팔로우

Jun 6

AI 엔지니어를 위한 FastAPI - 파트 3: 데이터베이스 연결하기

#ai #fastapi #python #backend

6 reactions댓글 추가

6분 읽기

왜 데이터 검증 (Data Validation)이 필요한가요?

날씨 애플리케이션을 구축하고 있다고 상상해 보세요.

사용자가 질문합니다:

Chennai의 기온은 얼마인가요?

유효한 응답은 다음과 같을 수 있습니다:

35

또는

35°C

하지만 만약 API가 다음과 같이 응답한다면 어떨까요?

Sunny

이것은 명백히 잘못되었습니다.

기온은 숫자로 표현되어야 합니다.

값 자체가 부정확하더라도, 기온은 반드시 숫자여야 한다는 점은 알 수 있습니다.

이 지점이 바로 검증 (Validation)이 중요해지는 부분입니다.

검증을 통해 데이터가 애플리케이션에 들어오기 전에 어떤 데이터가 허용 가능한지에 대한 규칙을 정의할 수 있습니다.

예를 들어:

  • 기온은 숫자여야 함
  • 나이는 음수일 수 없음
  • CGPA는 0과 10 사이여야 함
  • 이메일 주소는 유효한 형식을 따라야 함

검증이 없다면, 애플리케이션은 잘못된 데이터를 받아 예상치 못한 방식으로 동작할 수 있습니다.

검증이 없을 때 발생하는 문제

학생 등록 API를 예로 들어보겠습니다.

@app.post("/student")
def create_student(student):
    return student

사용자가 다음과 같은 데이터를 보낼 수 있습니다:

{
    "name": "Ananya",
    "cgpa": "Excellent"
...

API는 이를 수락할 것입니다.

하지만 CGPA(학점)는 텍스트가 아닌 숫자여야 합니다.

애플리케이션이 성장함에 따라, 모든 필드를 수동으로 확인하는 것은 어려워집니다.

더 나은 솔루션이 필요합니다.

Pydantic의 등장

Pydantic은 데이터 검증 (Data Validation)에 사용되는 Python 라이브러리입니다.

FastAPI는 내부적으로 Pydantic을 광범위하게 사용합니다.

데이터를 수동으로 검증하는 대신, 우리는 스키마 (Schema)를 정의합니다.

from pydantic import BaseModel

class Student(BaseModel):
...

이제 FastAPI는 다음 사항을 알게 됩니다:

  • name은 반드시 문자열 (String)이어야 함
  • cgpa는 반드시 부동 소수점 숫자 (Floating-point number)여야 함

데이터가 들어올 때마다, FastAPI는 이를 자동으로 검증합니다.

첫 번째 Pydantic 모델 만들기

from pydantic import BaseModel

class Student(BaseModel):
...

이 모델을 설계도 (Blueprint)라고 생각하세요.

모든 들어오는 요청은 이 구조를 따라야 합니다.

유효한 요청 (Valid Request)

{
    "name": "Ananya",
    "department": "CSE",
...

유효하지 않은 요청 (Invalid Request)

{
    "name": "Ananya",
    "department": "CSE",
...

FastAPI는 요청을 자동으로 거부할 것입니다.

FastAPI에서 Pydantic 사용하기

from fastapi import FastAPI
from pydantic import BaseModel

...

이 줄에 주목하세요:

student: Student

이제 FastAPI는 들어오는 요청 본문 (Request body)이 Student 스키마와 일치할 것을 기대합니다.

검증 오류 (Validation Errors) 이해하기

우리가 다음과 같은 데이터를 보낸다고 가정해 봅시다:

{
    "name": "Ananya",
    "department": "CSE",
...

FastAPI는 요청이 라우트 (Route)에 도달하기 전에 검증 오류를 반환합니다.

다음과 유사한 오류를 보게 될 것입니다:

{
    "detail": [
        {
...

FastAPI는 아무런 반응 없이 실패하는 대신, 무엇이 잘못되었는지 우리에게 명확하게 알려줍니다.

Field()를 사용한 제약 조건 추가

타입을 검증하는 것도 유용합니다.

하지만 때로는 더 엄격한 규칙이 필요할 때가 있습니다.

예를 들어:

  • CGPA는 0과 10 사이여야 함
  • 이름은 최소 길이를 가져야 함
  • 나이는 항상 양수여야 함

Pydantic은 이러한 목적을 위해 Field()를 제공합니다.

from pydantic import BaseModel, Field

class Student(BaseModel):
...

제약 조건 이해하기 (Understanding the Constraints)

cgpa: float = Field(gt=0, lt=10)

이것은 다음을 의미합니다:

CGPA > 0
CGPA < 10

유효한 요청 (Valid Request)

{
    "name": "Ananya",
    "cgpa": 8.9
...

유효하지 않은 요청 (Invalid Request)

{
    "name": "Ananya",
    "cgpa": 15
...

FastAPI는 즉시 해당 요청을 거부합니다.

선택적 필드 (Optional Fields)

때로는 필드가 필수 사항이 아닐 수도 있습니다.

예를 들어, 학생에게 아직 학과(department)가 할당되지 않았을 수 있습니다.

from typing import Optional
from pydantic import BaseModel

...

이제 department 필드는 선택 사항(optional)이 됩니다.

유효한 요청 (Valid Request)

{
    "name": "Ananya"
}

또한 유효함 (Also Valid)

{
    "name": "Ananya",
    "department": "CSE"
...

요청 모델 vs 데이터베이스 모델 (Request Models vs Database Models)

많은 초보자가 던지는 질문 중 하나는 다음과 같습니다:

schemas.pymodels.py가 둘 다 필요한가요?

그 차이점을 이해해 봅시다.

SQLAlchemy 모델 (SQLAlchemy Model)

class Student(Base):

    __tablename__ = "students"
...

이것은 데이터가 데이터베이스에 어떻게 저장되는지를 정의합니다.

Pydantic 모델 (Pydantic Model)

class StudentCreate(BaseModel):
    name: str
    cgpa: float

이것은 데이터가 우리 API로 어떻게 들어오는지를 정의합니다.

이렇게 생각하면 쉽습니다:

데이터베이스 구조 (Database Structure)
        ≠
API 구조 (API Structure)

두 구조가 비슷해 보일 수 있지만, 서로 다른 목적을 수행합니다.

응답 모델 (Response Models)

Pydantic은 API에서 반환되는 데이터도 제어할 수 있습니다.

class StudentResponse(BaseModel):
    id: int
    name: str
...
@app.get(
    "/student/{id}",
    response_model=StudentResponse
...

이를 통해 응답이 항상 일관된 구조를 따르도록 보장할 수 있습니다.

AI 애플리케이션에서 Pydantic이 중요한 이유

당신이 LLM API를 구축하고 있다고 가정해 봅시다.

예상되는 요청:

{
    "prompt": "Explain FastAPI",
    "temperature": 0.7,
...

검증(validation)이 없다면, 사용자는 다음과 같은 데이터를 보낼 수도 있습니다:

{
    "prompt": "Explain FastAPI",
    "temperature": "very creative",
...

그리고 여러분의 애플리케이션은 유효하지 않은 데이터를 처리해야만 할 것입니다.

Pydantic은 유효하지 않은 요청이 비즈니스 로직 (business logic)에 도달하는 것을 사전에 방지합니다.

이는 다음과 같은 시스템을 구축할 때 특히 중요해집니다:

  • AI 챗봇 (AI chatbots)
  • RAG 애플리케이션 (RAG applications)
  • 에이전틱 시스템 (Agentic systems)
  • 모델 추론 API (Model inference APIs)
  • 멀티 에이전트 워크플로우 (Multi-agent workflows)

검증 (Validation)이 요청 라이프사이클 (Request Lifecycle)에 포함되는 방식

Client Request
      │
      ▼
...

Pydantic은 첫 번째 방어선 역할을 합니다.

오직 유효한 데이터만이 애플리케이션의 나머지 부분에 도달합니다.

결론

Pydantic은 FastAPI가 이토록 인기를 얻게 된 이유 중 하나입니다. 이를 통해 우리는 더 안전하고, 예측 가능하며, 유지보수가 쉬운 API를 구축할 수 있습니다.

다음 기사에서는 인증 (Authentication) 및 인가 (Authorization)로 넘어가서, 권한이 없는 접근으로부터 API를 보호하는 방법을 배워보겠습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0