← 전체 글로 돌아가기

API

API pagination에서 page size 제한 두기

사용자가 원하는 page size를 모두 수용하면 서버에 부담이 된다. 적절한 제한을 두는 게 중요하다.

API에 pagination을 만들 때 page size를 마음대로 주는 건 위험하다. 누군가 ?limit=1000000을 요청하면 메모리를 다 먹거나 느려질 수 있다.

최대 page size 정하기

API를 설계할 때부터 page size 제한을 정한다. 보통 100~1000 사이가 무난하다.

# 잘못된 요청: 제한 없으면 터질 수 있다
curl 'https://api.example.com/items?page=1&limit=1000000'

# 좋은 방식: 제한이 있으면 무시하거나 최댓값으로 조정
curl 'https://api.example.com/items?page=1&limit=100' # OK
curl 'https://api.example.com/items?page=1&limit=1000' # 1000으로 제한됨

서버 코드에서 검증하기

API 핸들러에서 page size를 항상 검증한다.

app.get('/api/items', (req, res) => {
  let limit = parseInt(req.query.limit) || 20; // 기본값 20
  const MAX_LIMIT = 100;

  if (limit > MAX_LIMIT) {
    limit = MAX_LIMIT;
  }
  if (limit < 1) {
    limit = 1;
  }

  const page = parseInt(req.query.page) || 1;
  const offset = (page - 1) * limit;

  // 데이터베이스에서 가져올 때 limit 적용
  const items = db.query(
    'SELECT * FROM items LIMIT ? OFFSET ?',
    [limit, offset]
  );

  res.json({ items, total: items.length, limit, page });
});

클라이언트에서 보여줄 정보

API 응답에 현재 제한 값을 포함하면 클라이언트가 UI를 더 잘 만들 수 있다.

{
  "items": [...],
  "limit": 100,
  "requested_limit": 1000,
  "page": 1,
  "total": 5000,
  "has_next": true
}

이렇게 하면 클라이언트에서 "요청한 limit이 조정됐다"는 걸 알 수 있다.

시간 기반 페이징도 고려하기

offset 기반 pagination은 대량 데이터에서 느릴 수 있다. cursor 기반이나 시간 기반으로 하면 훨씬 빠르다.

# 시간 기반: 마지막 항목의 timestamp 이후로 가져오기
curl 'https://api.example.com/items?after=2024-01-01T10:00:00Z&limit=20'

page size 제한은 작은 것처럼 보이지만 운영 환경에서는 꼭 필요한 보호장치다.