🚀 94sssh
Published on

2026.03.07

[실전 API 설계] - 17. 컬렉션 엔드포인트에 필터와 페이징 적용

17.1. 문제

필터링, 페이징, 정렬은 GET을 사용하는데, GET은 요청 본문을 사용할 수 없다.

  • 쿼리 파라미터: API 요청 입력값, 리소스나 리소스 컬렉션 식별
  • HTTP 헤더: 인가 정보 등 API 요청의 메타 정보 제공, 리소스 식별과는 관계 X

두 가지 옵션 중 의미상으로 적합한 쿼리 파라미터를 사용.

17.2. 필터링 설계

필터에는 두 가지 타입이 있다.

  • 프로젝션 필터: 리소스의 필드 중에서 일부 필드만을 추출
  • 셀렉션 필터: 컬렉션의 부분집합을 선택

17.2.1. 프로젝션 필터

셀렉션 필터만큼 자주 쓰이진 않으며, 아주 많은 수의 필드를 가진 무거운 스키마에서만 쓸모가 있다.
프로젝션 필터는 fields 쿼리 파라미터를 사용하는 것이 관례.
id, name, email 필드를 갖고 있는 Customer 스키마에서 이름과 이메일 주소만 필요하다면 GET /customers?fields=name,email과 같이 요청.

17.2.2. 셀렉션 필터

리소스의 특성을 검사해 조건을 만족시키는 리소스만 응답에 포함.
필터 조건은 하나의 값만 사용할 수도 있고, 범위를 지정할 수도 있음.

17.2.3. 중첩 스키마 처리

{
  "name": "John Doe",
  "email": "johndoe@example.com",
  "address": {
    "country": "US",
    "zip_code": "12345",
    "city": "Boomtown"
  }
}

country를 필터링한다고 했을 때, 필드를 지정할 수 있는 방법 중 맞는 방식

  • country: 어느 country를 지칭하는지 알 수 없으므로 사용 X
  • address_country: 스네이크 케이스와 충돌할 수 있으므로 사용 X, 이름이 address_country인지, address의 country인지 모호
  • address.country: O
  • address[country]: O

17.2.4. 쿼리 언어

쿼리 파라미터의 값으로 쿼리 언어를 지정할 수 있으나, URL 최대 길이 한도를 초과하는 쿼리 언어 등은 쿼리 파라미터로 사용할 수 없음. 그러면 POST를 호출해야 하는데, 조회에 POST 사용은 HTTP 문법에 위배 및 HTTP 캐싱을 사용할 수 없으므로 쿼리 파라미터를 단순하게 설계하는 편이 낫다.

17.2.5. 특수 관례

  • 다른 스키마를 가리키는 필드에 대해서는 서브리소스 컬렉션 엔드포인트를 사용
  • question이나 query를 의미하는 q를 필터링 파라미터 이름으로 사용, 여러 필드에 걸쳐 전문 검색을 지원하기 위함.

17.4. 페이징 설계

페이징 구현 방식은 일반적으로 두 가지로 구분

  • 오프셋 기반, 페이지 기반 페이징
  • 커서 기반 페이징

17.4.1. 오프셋 기반, 페이지 기반 페이징

공통적으로 2개의 쿼리 파라미터를 받는다.

  1. 한 페이지에 표시할 결과물의 개수, 보통 limit이나 per_page로 부른다.
  2. 결과물 목록의 시작점, 보통 offset이나 page 파라미터로 부른다. 기본값은 0으로 목록의 첫 번째부터 조회.

오프셋 기반 페이징은 항상 모든 결과물을 대상으로 처음부터 offset을 카운트한다.
오프셋 기반 페이징은 결과물의 총 개수(count, total_results 등)를, 페이지 기반 페이징은 총 페이지 개수(page_count 등)를 리턴하는 것이 좋음.

17.4.2. 커서 기반 페이징

2개의 쿼리 파라미터가 필요함.

  1. 한 페이지에 표시될 결과물의 개수
  2. 페이지를 식별할 수 있는 cursor, 이전 요청의 응답으로 받을 수 있음.

다음 게시물 요청시 cursor를 쿼리 파라미터에 포함해서 요청하고, 마지막 페이지에서는 cursor에 null을 리턴한다.

장점: 중간에 게시물이 추가되어도 cursor 값이 같은 ID를 가리키고 있으므로 다음 페이지 조회시 기존과 동일하게 동작. 오프셋 기반 페이징은 게시물이 밀림 단점: 페이지를 건너뛸 수 없음

17.6. 정렬 설계

17.6.1. 단일 필드 정렬

sort_by=name:asc, sort_by=name:desc 등으로 정렬 기준과 방향을 표현

17.6.2. 다중 필드 정렬

쉼표 등을 구분자로 사용

sort_by=city:asc,name:asc

17.6.3. 파라미터 타입 일관성

정렬, 필터링 파라미터 등 일관성을 유지하기 위한 스타일

  1. 길고 사람이 이해하기 쉬운 파라미터 이름을 사용, 특수문자 사용 X
  2. 모든 세부 사항은 lt, desc 같은 키워드와 일관성 있는 구분자 (:)를 사용해 값 쪽에 기술
  3. 특수문자 접두어(<, -)를 사용해 세부 사항의 텍스트 길이를 줄임