[FastAPI] Todo 예제로 배우는 RESTful API 설계
by rowing0328※ 이 글은 이노그리드 교육 과정의 일부로, 저만의 관점과 해석을 더해 작성되었습니다.
Intro
이전 글에서 FastAPI 기본기와 APIRouter로 라우팅을 분리하는 방법까지 배워봤다.
이번에는 한 단계 더 나아가 실제로 "할 일(Todo) API"를 직접 만들어보며,
다음과 같은 핵심 포인트들을 정리해보려 한다:
- Restful 설계
- Pydantic 모델 도입
- Path/Query 활용
- 응답 모델/데이터 필터링
- HTTP 오류 처리
이런 실무 핵심 포인트를 단계별로 정리해 본다.
처음 FastAPI 실전 프로젝트를 설계하거나,
실제 API 품질을 끌어올리고 싶은 분께 도움이 되길 바란다.
할 일(Todo) 서비스, RESTful 하게 설계하기
FastAPI에서 가장 기본이 되는 구조는 "라우팅"이다.
이번 실습에서는 할 일 추가, 조회, 수정, 삭제 등
RESTful하게 주소와 동작을 정리한다.
[ 예제 코드 ]
from fastapi import APIRouter
from typing import List
router = APIRouter(prefix="/todos", tags=["todos"])
@router.post("/", summary="할 일 추가")
def create_todo(...): ...
@router.get("/", summary="할 일 전체 목록")
def list_todos(...): ...
@router.get("/{todo_id}", summary="할 일 상세조회")
def get_todo(todo_id: int): ...
@router.put("/{todo_id}", summary="할 일 수정")
def update_todo(todo_id: int, ...): ...
@router.delete("/{todo_id}", summary="할 일 삭제")
def delete_todo(todo_id: int): ...
Restful 설계 원칙대로 아래와 같이 일관성 있게 설계한다:
- 목록은 GET /todos
- 등록은 POST /todos
- 단건조회는 GET /todos/{id}
- 수정은 PUT /todos/{id}
- 삭제는 DELETE /todos/{id}
검색 등 특수 기능은 일반적으로 GET /todos/search처럼 별도 경로로 먼저 선언한다.
Pydantic으로 데이터 모델과 검증 자동화
FastAPI의 진짜 강점은 Pydantic 모델을 활용한 데이터 유효성 자동 검증이다.
예를 들어 Todo의 기본 정보는 다음처럼 작성할 수 있다.
from pydantic import BaseModel, Field
from typing import Optional
class Todo(BaseModel):
id: int
title: str = Field(..., min_length=1, max_length=100)
description: Optional[str] = Field(None, max_length=500)
is_done: bool = False
- 타입/필수성/길이 등 유효성 조건을 코드 한 줄로 지정할 수 있다.
- API 호출 시 잘못된 값이 오면, 자동으로 "400 에러"와 상세 메시지가 반환된다.
- id 필드는 응답(response)에만 사용, 등록/수정 등에는 별도 모델 분리
중첩 모델·수정 모델로 역할 분리
등록할 때와 수정할 때,
모든 필드가 필요한 게 아니다.
예를 들어,
- 새로 등록할 때는 title, description만 필요 (id는 필요 없음)
- 수정할 때는 일부 필드만 받을 수 있음
그래서 다음처럼 중첩/수정 모델을 별도로 만든다.
class TodoCreate(BaseModel):
title: str = Field(..., min_length=1)
description: Optional[str] = None
class TodoUpdate(BaseModel):
title: Optional[str] = Field(None, min_length=1)
description: Optional[str] = None
is_done: Optional[bool] = None
- 각 API에서 적절한 모델을 사용하면, 불필요한 필드 요구를 없애고, 자동 문서화에도 정확히 반영된다.
Path & Query 매개변수 세밀하게 다루기
FastAPI의 또 하나의 실전은 Path, Query 클래스로
입력값 검증과 문서화 메타 정보를 더 세밀하게 컨트롤하는 것이다.
[ 예제 코드 ]
from fastapi import Path, Query
@router.get("/{todo_id}")
def get_todo(
todo_id: int = Path(..., title="Todo ID", ge=1, description="할 일의 고유 번호")
):
...
@router.get("/search")
def search_todos(
keyword: str = Query(..., min_length=1, max_length=30, description="검색어")
):
...
- Path, Query를 사용하면 입력값 제한, 설명, 예시 등 문서화도 자동 반영된다.
- todo_id는 1 이상이어야만 하도록 제한한다.
- keyword는 최소 1자, 최대 30자로 제한한다.
라우터 선언 순서 주의
/todos/search 등 구체적인 경로를
/todos/{todo_id}(경로 매개변수) 보다 반드시 먼저 선언해야
경로 충돌을 방지할 수 있다.
응답과 데이터 필터링
FastAPI에서는 각 API의 반환 데이터 구조도 response_model로 명확히 지정할 수 있다.
[ 예제 코드 ]
class TodoSummary(BaseModel):
title: str
is_done: bool
@router.get("/summaries", response_model=List[TodoSummary])
def list_todo_summaries(): ...
- 불필요한 내부 데이터(id 등)를 빼거나 사용자 요구에 맞는 "커스텀 응답"을 쉽게 만들 수 있다.
HTTP 오류 처리 및 표준화
실제 실무 API에서는
적절한 HTTP 상태 코드와 에러 메시지 전달이 매우 중요하다.
FastAPI에서는 HTTPException을 활용해
시나리오별로 정확한 코드와 메시지를 반환한다.
[ 예제 코드 ]
from fastapi import HTTPException
@router.get("/{todo_id}")
def get_todo(todo_id: int):
todo = db.get(todo_id)
if not todo:
raise HTTPException(status_code=404, detail="할 일을 찾을 수 없음")
return todo
@router.post("/", status_code=201)
def create_todo(...):
...
- 404 Not Found, 201 Created, 200 OK 등 시나리오별 올바른 상태 코드를 사용
- 에러 발생 시 클라이언트가 명확한 원인을 확인 가능 → 신뢰성/예측성 향상
마무리
이번 글에서는 FastAPI로 간단한 Todo API를 만들면서,
실무에서 자주 마주치는 핵심 개념들을 단계적으로 정리했다.
단순히 작동하는 API를 넘어서,
읽기 쉽고 유지보수하기 좋은 구조를 갖춘 API를 만드는 데 집중했다.
FastAPI는 이런 설계를 빠르게 구현할 수 있도록 돕는 훌륭한 프레임워크다.
이번 내용을 바탕으로 첫 프로젝트를 더 탄탄하게 설계할 수 있기를 바란다.
다음 글에서는 데이터베이스 연동을 다뤄볼 예정이다.
참고 자료:
FastAPI Official Web Site - Path Parameters
Path Parameters - FastAPI
FastAPI framework, high performance, easy to learn, fast to code, ready for production
fastapi.tiangolo.com
FastAPI Official Web Site - Query Parameters
Query Parameters - FastAPI
FastAPI framework, high performance, easy to learn, fast to code, ready for production
fastapi.tiangolo.com
'🌈Programming > FastAPI' 카테고리의 다른 글
[FastAPI] APIRouter로 라우팅 구조화하기 (0) | 2025.05.19 |
---|---|
[FastAPI] 파이썬으로 웹 API 개발 시작하기 (0) | 2025.05.19 |
블로그의 정보
코드의 여백
rowing0328