본문으로 건너뛰기
백엔드 기초집: Python FastAPILESSON 18

페이지네이션, 정렬, 검색 API

난이도초급
예상 시간35분
선수지식이전 강의

18강. 페이지네이션, 정렬, 검색 API

1. 이번 강의에서 해결할 문제

기록이 많아지면 전체 행을 한 번에 반환할 수 없습니다. 페이지 크기를 제한하고 게임 이름 검색과 안전한 정렬을 추가합니다.

2. 학습 목표

3. 핵심 개념

페이지네이션은 응답 크기와 DB 부하를 제한합니다. 정렬 열을 사용자 문자열로 SQL에 직접 넣으면 injection과 예측하지 못한 열 접근 위험이 있으므로 코드의 dict에서 선택합니다. %, _가 포함된 검색 정책도 정하고 실서비스에서는 인덱스와 검색 성능을 측정해야 합니다.

4. 단계별 코드 예시

파일 경로: game-ranking-api/app/schemas/record.py

app/schemas/record.py
from pydantic import BaseModel


class RecordPage(BaseModel):
items: list[RecordRead]
total: int
offset: int
limit: int

파일 경로: game-ranking-api/app/routers/records.py

app/routers/records.py
from typing import Annotated, Literal

from fastapi import Query
from sqlalchemy import func, select


@router.get("", response_model=RecordPage)
def list_records(
db: DbSession,
q: Annotated[str | None, Query(min_length=1, max_length=80)] = None,
offset: Annotated[int, Query(ge=0)] = 0,
limit: Annotated[int, Query(ge=1, le=100)] = 20,
sort: Literal["created_at", "score"] = "created_at",
order: Literal["asc", "desc"] = "desc",
) -> RecordPage:
filters = []
if q:
filters.append(GameRecord.game_name.ilike(f"%{q}%"))

sort_columns = {"created_at": GameRecord.created_at, "score": GameRecord.score}
sort_column = sort_columns[sort]
order_expression = sort_column.asc() if order == "asc" else sort_column.desc()

item_stmt = select(GameRecord).where(*filters).order_by(order_expression, GameRecord.id).offset(offset).limit(limit)
count_stmt = select(func.count()).select_from(GameRecord).where(*filters)
return RecordPage(
items=list(db.scalars(item_stmt)),
total=db.scalar(count_stmt) or 0,
offset=offset,
limit=limit,
)

실행 위치: game-ranking-api/

python -m uvicorn app.main:app --reload
Invoke-RestMethod 'http://127.0.0.1:8000/records?q=rule&sort=score&order=desc&offset=0&limit=10'
Invoke-WebRequest 'http://127.0.0.1:8000/records?sort=password_hash' -SkipHttpErrorCheck

5. 코드가 동작하는 이유

items와 count 문장이 같은 filters를 공유해 total 의미가 일치합니다. Literal이 문서와 검증에서 허용값을 제한하고 dict가 실제 Column으로 변환합니다. 두 번째 id 정렬은 점수가 같아도 페이지 순서를 안정적으로 만듭니다.

6. 자주 하는 실수와 해결법

7. 직접 실습

8. 이해 점검 질문 3개

9. 핵심 요약

MINI QUIZ

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“페이지네이션, 정렬, 검색 API” 작업 전 검토에서 채택해야 할 안전 기준은 무엇인가요?
  2. 문제 2‘order_by(text(user_input))를 사용합니다.’ 실수를 판단할 때 “페이지네이션, 정렬, 검색 API” 강의가 제시한 기준은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

18강. 페이지네이션, 정렬, 검색 API 미완료 상태