FastAPI — 타입이 곧 계약이다 · 누락과 중복 없는 커서 페이지네이션 · 실습
누락과 중복 없는 커서 페이지네이션
목표
정렬·필터·커서·응답 투영을 분리하고 FastAPI 요청으로 다시 연결합니다.
왜 중요한가
정상 요청 한 번의 성공은 경계값과 장애 복구를 보장하지 않습니다. 이 실습은 각 함수의 계약을 작게 구현하거나 테스트한 뒤 실제 실행으로 연결합니다. 코드가 존재하는지나 보고서 문구만 보지 않고 결과·예외·저장 상태를 검사합니다. 앞 단계의 코드를 유지하며 다음 단계로 진행하세요.
단계
1. /root/work/fa-pagination-lab/service.py에서 parse_limit(value)는 문자열 정수를 받아 1~50이면 int를 반환하고 나머지는 ValueError로 거절하세요. 첫 준비는 다음 명령으로 합니다.
mkdir -p /root/work/fa-pagination-labcp /opt/fixtures/practice_depth/fa-pagination-lab/* /root/work/fa-pagination-lab/cd /root/work/fa-pagination-lab2. /root/work/fa-pagination-lab/service.py에서 ordered_rows(rows)는 id 오름차순의 새 리스트를 반환하세요. 입력 rows는 바꾸지 않습니다. 각 행은 고유한 양의 정수 id와 name, category, internal_cost를 가집니다.
3. /root/work/fa-pagination-lab/service.py에서 filter_rows(rows, category=None)는 category가 None이면 전체, 지정되면 정확히 같은 범주만 원래 순서로 반환하세요. 없는 범주는 빈 리스트입니다.
4. /root/work/fa-pagination-lab/service.py에서 encode_cursor(item_id)는 양의 정수 id의 십진 문자열을 UTF-8로 바꾼 뒤 padding을 포함한 URL-safe base64 문자열을 반환하세요.
5. /root/work/fa-pagination-lab/service.py에서 decode_cursor(token)는 위 커서를 양의 정수로 복원하세요. 잘못된 base64, 빈 값, 0·음수·숫자 아닌 값은 ValueError입니다. ASCII 십진 숫자만 허용하며 개행·쓰레기 문자를 무시하지 마세요.
6. /root/work/fa-pagination-lab/service.py에서 page_after(rows, after, limit)는 id > after인 행을 오름차순으로 limit개까지 반환하세요. 반환은 (page, next_cursor)이며 남은 행이 있을 때만 page의 마지막 id를 인코딩합니다. 빈 목록과 끝에서는 None입니다.
7. /root/work/fa-pagination-lab/service.py에서 public_item(row)는 id, name, category만 담은 새 딕셔너리를 반환하세요. 원본의 internal_cost는 삭제하거나 수정하지 않습니다.
8. /root/work/fa-pagination-lab/service.py에서 create_app(rows)는 GET /items를 가진 FastAPI 앱을 반환하세요. limit 기본 10, after 기본 없음, category 기본 없음입니다. 앞 함수를 조합해 {items: [...], next_cursor: 문자열 또는 null}을 반환하고 잘못된 limit·after는 422로 응답하세요.
참고
- 패키지는 이미지에 설치돼 있습니다. 인터넷 연결이나 pip install은 필요하지 않습니다.
- 준비 복사는 최초 한 번만 하세요. 다시 복사하면 작업 파일이 초기화됩니다.
- 채점은 여러분의 service.py를 불러와 다른 id와 임시 저장소로 실행합니다. 결과를 상수로 박지 마세요.
- 각 단계 채점은 45초 안에서 실행됩니다. 무한 루프나 실제 대기를 만들지 마세요.
8단계
- limit 범위를 계약으로 고정한다
- 입력 순서와 응답 순서를 분리한다
- 페이지보다 필터를 먼저 적용한다
- 마지막 id를 커서로 표현한다
- 깨진 커서를 일찍 거절한다
- 마지막 페이지를 정확히 구분한다
- 응답에서 내부 필드를 제거한다
- 실제 HTTP 계약으로 합친다