
지난 시간에는 Path Parameter와 Query Parameter를 통해 URL에서 데이터를 받는 방법을 배웠습니다. 하지만 실제 API를 개발할 때는 더 복잡한 데이터 구조를 다뤄야 합니다. 예를 들어, 사용자 정보를 생성하거나 상품 정보를 수정할 때는 여러 필드를 포함한 복잡한 데이터를 주고받아야 하죠.

오늘은 FastAPI에서 데이터 모델링의 핵심인 Python Type Hints와 Pydantic에 대해 알아보겠습니다. 이 두 기술을 마스터하면 타입 안전성을 보장하면서도 강력한 데이터 검증 기능을 갖춘 API를 만들 수 있습니다.

FastAPI는 Python 객체(dict, list 등)를 HTTP 응답으로 보낼 때 자동으로 JSON으로 변환합니다. 이 과정을 직렬화(Serialization)라고 하며, 반대로 JSON을 Python 객체로 변환하는 과정을 역직렬화(Deserialization)라고 합니다.
Python과 JSON의 타입 매핑:
dict → JSON Object {}list, tuple, set → JSON Array []str → JSON Stringint, float → JSON NumberTrue/False → JSON true/falseNone → JSON nullfrom fastapi import FastAPI
app = FastAPI()
@app.get("/items")
def get_items():
return {
"items": ["apple", "banana"],
"count": 2,
"available": True
}
FastAPI가 자동으로 이 Python dict를 JSON으로 변환하여 클라이언트에게 전송합니다.

Python 3.5부터 도입된 Type Hints는 변수와 함수의 타입을 명시적으로 선언할 수 있게 해줍니다.
def greet(name: str) -> str:
return f"Hello, {name}!"
age: int = 25
price: float = 19.99
is_active: bool = True
Type Hints의 장점:
1. 가독성 향상: 코드를 읽는 사람이 변수의 타입을 즉시 이해할 수 있습니다
2. IDE 지원: 자동 완성과 타입 체크 기능 활용 가능
3. FastAPI 통합: FastAPI가 타입 정보를 활용해 자동으로 검증합니다
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
/users/123 → 정상 작동 ✅/users/abc → 422 에러 발생 ❌FastAPI가 자동으로 타입을 검증하고 잘못된 타입이 들어오면 422 Unprocessable Entity 에러를 반환합니다.
from typing import List, Dict
scores: List[int] = [80, 90, 100]
user: Dict[str, str] = {"name": "Alice", "email": "alice@example.com"}
users: List[Dict[str, str]] = [
{"name": "Bob", "email": "bob@example.com"},
{"name": "Charlie", "email": "charlie@example.com"}
]
값이 있을 수도 있고 없을 수도 있는 경우 Optional을 사용합니다.
from typing import Optional
def find_user(user_id: int) -> Optional[str]:
# 사용자를 찾으면 이름을 반환, 없으면 None 반환
if user_id == 1:
return "Alice"
return None
# Query Parameter에서 Optional 사용
@app.get("/search")
def search(q: Optional[str] = None):
if q:
return {"query": q}
return {"message": "No query provided"}
Pydantic은 Python 타입 힌트를 사용하여 데이터 검증과 설정 관리를 수행하는 라이브러리입니다. FastAPI의 핵심 기능 중 하나죠.


from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
is_offer: bool = False # 기본값 설정
이렇게 정의한 모델은:
name: 필수 문자열 필드price: 필수 실수 필드is_offer: 선택적 불리언 필드 (기본값 False)# 올바른 데이터 - 성공 ✅
item_success = Item(name="Apple", price=100)
# 잘못된 타입 - ValidationError 발생 ❌
try:
item_fail = Item(name="Banana", price="hello") # price는 float이어야 함
except Exception as e:
print(e)
Pydantic은 타입이 맞지 않으면 ValidationError를 발생시키고, FastAPI는 이를 422 HTTP 에러로 변환합니다.

GET 요청은 URL에 데이터를 포함하지만, POST/PUT 요청은 Request Body에 데이터를 담아 보냅니다. 주로 복잡한 데이터를 생성하거나 수정할 때 사용합니다.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class ItemCreate(BaseModel):
name: str
price: float
description: Optional[str] = None
@app.post("/items")
def create_item(item: ItemCreate):
return {
"message": "Item created",
"name": item.name,
"price": item.price
}
Swagger UI에서 테스트:
1. http://127.0.0.1:8000/docs 접속
2. POST /items 엔드포인트 선택
3. "Try it out" 클릭
4. Request Body 입력:
{
"name": "Laptop",
"price": 1200.50,
"description": "High performance laptop"
}

FastAPI는 매개변수의 타입을 보고 자동으로 구분합니다:
{user_id})@app.put("/users/{user_id}/items/{item_id}")
def update_item(
user_id: int, # Path Parameter
item_id: int, # Path Parameter
item: ItemCreate, # Request Body
q: Optional[str] = None # Query Parameter
):
return {
"user_id": user_id,
"item_id": item_id,
"item": item,
"q": q
}

class Item(BaseModel):
name: str
price: float
description: Optional[str] = None # 선택적 필드
tax: float = 0.1 # 기본값 0.1
description은 제공하지 않아도 됨 (None)tax는 제공하지 않으면 0.1로 설정됨
API 응답에서 특정 필드를 제외하고 싶을 때가 있습니다. 예를 들어, 사용자 정보를 반환할 때 비밀번호는 제외해야 하죠.

class UserCreate(BaseModel):
email: str
password: str
class UserResponse(BaseModel):
id: int
email: str
# password 필드 없음!
@app.post("/signup", response_model=UserResponse)
def signup(user: UserCreate):
# DB에 저장하는 로직...
return {
"id": 1,
"email": user.email,
"password": user.password # 이 값은 응답에서 제외됨!
}
response_model=UserResponse를 지정하면:
UserResponse 스키마에 맞춰 응답을 필터링합니다password 필드는 응답 JSON에서 제외됩니다UserResponse 스키마가 표시됩니다
오늘 배운 내용을 정리하면:

✅ 직렬화/역직렬화: Python 객체 ↔ JSON 변환 자동화
✅ Type Hints: 타입 명시로 코드 안전성 향상
✅ List, Dict, Optional: 복합 타입 활용
✅ Pydantic BaseModel: 강력한 데이터 검증과 모델링
✅ Request Body: POST/PUT 요청으로 복잡한 데이터 받기
✅ Response Model: 응답 데이터 제어 및 보안
Pydantic과 Type Hints는 FastAPI의 핵심 기능입니다. 이를 제대로 활용하면 타입 안전성을 보장하면서도 자동 검증, 자동 문서화를 모두 얻을 수 있습니다. 다음 시간에는 더 고급 Pydantic 기능과 데이터베이스 연동에 대해 알아보겠습니다!


참고 자료: