Backend Framework/FastAPI
03. FastAPI - Request Body(JSON), Form(HTML) 처리
Python Developer
2025. 4. 22. 21:26
FastAPI - Request Body 및 Form 데이터 처리
FastAPI에서는 클라이언트로부터 데이터를 받을 때, 전송 방식에 따라 JSON(Request Body) 또는 Form(FormData)으로 분리하여 처리할 수 있다. 요청 방식에 따라 HTTP 요청 헤더의 Content-Type
이 달라지고, FastAPI는 이를 기반으로 적절하게 데이터를 파싱한다.
📦 Request Body 처리 (application/json)
✅ 기본 사용: Pydantic 모델 기반 요청
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
@app.post("/items/")
async def create_item(item: Item):
return item
요청 예시 (curl)
curl -X 'POST' 'http://localhost:8000/items/' \
-H 'Content-Type: application/json' \
-d '{
"name": "Laptop",
"price": 999.99,
"tax": 10.0
}'
응답 예시
{
"name": "Laptop",
"description": null,
"price": 999.99,
"tax": 10.0
}
✅ 계산 포함 응답 처리
@app.post("/items/with-tax/")
async def create_item_with_tax(item: Item):
item_dict = item.model_dump()
if item.tax:
item_dict["price_with_tax"] = item.price + item.tax
return item_dict
요청
curl -X 'POST' 'http://localhost:8000/items/with-tax/' \
-H 'Content-Type: application/json' \
-d '{
"name": "Desk",
"price": 150.0,
"tax": 15.0
}'
응답
{
"name": "Desk",
"description": null,
"price": 150.0,
"tax": 15.0,
"price_with_tax": 165.0
}
✅ Path + Query + Request Body 함께 사용
@app.put("/items/{item_id}/")
async def update_item(item_id: int, item: Item, q: Optional[str] = None):
result = {"item_id": item_id, **item.model_dump()}
if q:
result["q"] = q
return result
요청
curl -X 'PUT' 'http://localhost:8000/items/1/?q=search-keyword' \
-H 'Content-Type: application/json' \
-d '{
"name": "Tablet",
"price": 299.99
}'
응답
{
"item_id": 1,
"name": "Tablet",
"description": null,
"price": 299.99,
"tax": null,
"q": "search-keyword"
}
✅ 다중 Request Body 처리
class User(BaseModel):
username: str
full_name: Optional[str] = None
@app.put("/items/{item_id}/with-user/")
async def update_item_with_user(item_id: int, item: Item, user: User):
return {"item_id": item_id, "item": item, "user": user}
요청
curl -X 'PUT' 'http://localhost:8000/items/5/with-user/' \
-H 'Content-Type: application/json' \
-d '{
"item": {
"name": "Monitor",
"price": 199.99
},
"user": {
"username": "johndoe",
"full_name": "John Doe"
}
}'
응답
{
"item_id": 5,
"item": {
"name": "Monitor",
"description": null,
"price": 199.99,
"tax": null
},
"user": {
"username": "johndoe",
"full_name": "John Doe"
}
}
📝 Form 데이터 처리 (application/x-www-form-urlencoded)
✅ 기본 Form 처리
from fastapi import FastAPI, Form
from typing import Annotated
app = FastAPI()
@app.post("/login/")
async def login(
username: str = Form(),
email: str = Form(),
country: Annotated[str, Form()] = None
):
return {
"username": username,
"email": email,
"country": country
}
요청 예시
curl -X 'POST' 'http://localhost:8000/login/' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'username=alice&email=alice@example.com&country=KR'
응답
{
"username": "alice",
"email": "alice@example.com",
"country": "KR"
}
✅ Path + Query + Form 혼합 사용
@app.post("/login/{login_type}/")
async def login_with_path_query(
login_type: int,
q: Optional[str] = None,
username: str = Form(),
email: str = Form(),
country: Annotated[str, Form()] = None
):
return {
"login_type": login_type,
"q": q,
"username": username,
"email": email,
"country": country
}
요청 예시
curl -X 'POST' 'http://localhost:8000/login/2/?q=fastapi' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'username=bob&email=bob@example.com&country=US'
응답
{
"login_type": 2,
"q": "fastapi",
"username": "bob",
"email": "bob@example.com",
"country": "US"
}
✅ 요약
요청 방식 | Content-Type | 처리 방식 |
---|---|---|
JSON Body | application/json |
Pydantic 모델 사용 |
Form | application/x-www-form-urlencoded |
Form() 사용 |
- 요청의 Content-Type에 따라 적절한 파라미터 처리 방식이 필요하다.
- FastAPI는 타입 힌트를 기반으로 자동 유효성 검사 및 문서 생성을 지원한다.