본문으로 건너뛰기
백엔드 기초집: 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 미완료 상태