목록 API가 HTTP 200을 반환했고 데이터도 보인다면 전체 수집이 끝난 것일까? 요청 성공, 페이지 순회 완료, 업무에 필요한 범위 확보는 각각 확인해야 한다. 첫 페이지를 정상적으로 받아도 다음 페이지가 남을 수 있고, 끝까지 읽었더라도 필터·계정 권한으로 제외된 자료까지 받은 것은 아니다.
이 글은 문서·업무 AI에 공급할 외부 목록을 수집하는 담당자를 위한 설명이다. 아래 여섯 ID와 응답은 합성 자료이며 로컬 Python에서만 확인했다. 실제 GitHub 목록·개인 계정·고객 자료를 조회한 시험은 아니다.
첫 응답의 두 건과 세 페이지의 여섯 건은 다르다
가상의 원목록이 ID 1~6이고 페이지 크기가2라고 하자. 첫 응답의 items는[1,2], 다음은[3,4], 마지막은[5,6]이다. 모두 성공 응답이지만 첫 페이지만 저장한 결과는2건이고, 다음 위치를 따라 세 페이지를 읽은 결과는6건이었다.
# 실제 HTTP 클라이언트가 아닌 합성 응답 어댑터다.
pages = {
1: {'status': 200, 'items': [1, 2], 'next': 2},
2: {'status': 200, 'items': [3, 4], 'next': 3},
3: {'status': 200, 'items': [5, 6], 'next': None},
}
collected, visited = [], []
page = 1
while page is not None:
if page in visited:
raise ValueError('repeated page')
visited.append(page)
response = pages[page]
if response['status'] != 200:
raise ValueError('incomplete read')
collected.extend(response['items'])
page = response['next']
# collected == [1, 2, 3, 4, 5, 6]
# visited == [1, 2, 3]
여기서 next=None은 이 가상 어댑터의 종료 규칙이다. 실제 API에 같은 필드가 있다고 가정해서는 안 된다. 마지막 페이지를 확인하지 못한 채 중간 응답이 끊겼다면, 지금까지 저장한 부분과 마지막 확인 위치를 남기고 ‘전체 완료’라고 표시하지 않는다.
제품 문서의 다음 페이지 표시를 읽는다
GitHub REST 페이지네이션 문서는 Link 응답 헤더의 rel=”next” URL로 다음 페이지를 요청하는 방법을 설명한다. prev·first·last 중 일부만 제공될 수 있고, 마지막 위치를 계산할 수 없으면 last 링크도 없을 수 있다. 페이지 번호를 임의로 만들기보다 해당 응답이 제공하는 다음 URL과 엔드포인트 계약을 따른다.
per_page도 페이지당 요청량이지 전체 자료 수가 아니다. GitHub 문서는 이를 지원하는 엔드포인트에서 사용할 수 있고 대다수의 최대값은100이라고 안내하지만, 정확한 기본값·최댓값은 해당 엔드포인트에서 확인하도록 한다. 큰 값을 넣어 성공 응답을 받았다는 사실만으로 한 번에 모두 반환됐다고 할 수 없다.

다른 제품은 본문의 토큰이나 별도 필드를 쓸 수 있다. 예를 들어 Google Calendar Events.list 문서는 더 결과가 있어도 한 페이지의 항목 수가 요청한 최대보다 적거나0일 수 있고, nextPageToken으로 남은 페이지를 구분한다고 설명한다. ‘빈 배열이면 모든 API에서 끝’이라는 규칙도 맞지 않는다.
끝 표시와 수집 범위를 함께 남긴다
| 확인 지점 | 남길 근거 | 그것만으로 모르는 것 |
|---|---|---|
| 요청 성공 | 상태와 실제 응답 해석 | 다음 페이지의 존재 |
| 순회 완료 | 문서화된 끝 표시·방문한 위치 | 필터·권한 밖의 자료 |
| 대상 범위 | 엔드포인트·필터·권한 범위 | 조회 중 자료가 고정됐는지 |
| 결과 대조 | 수신 건수·고유 ID·총수의 뜻 | 개수가 같아도 ID가 같은지 |
이 표는 작성자의 수집 점검 제안이다. 같은 가상 원목록6건 중 조회 계정과 필터가 허용한 ID가1·2·3뿐이라면, 그 범위의 두 페이지를 끝까지 읽은3건은 올바른 결과일 수 있다. 이를 원시스템 전체6건 확보라고 쓰면 범위를 넓힌 셈이다. 필요한 대상이 더 넓다면 조회 권한이나 필터를 확인할 책임이 남는다.
총수가 제공돼도 현재 필터 결과인지, 계정에서 보이는 수인지, 다른 시점의 값인지 확인한다. 같은 건수가 나왔다는 것만으로 모든 ID가 일치하지는 않는다. 더 큰 권한을 자동으로 얻거나 별도 계정으로 우회하는 일이 아니라, 허용된 수집 범위와 부족한 근거를 정확히 표시하는 일이다.
순회 완료 다음에도 별도의 문제가 남는다
페이지를 정상 순회했는데 누락이 보인다면 offset과 조회 중 목록 변경을 구별한다. 다음 수집에서 바뀐 자료를 이어받으려면 갱신 시각·동기화 토큰의 진행 경계를 확인한다. 이 글의 여섯 건 예는 고정된 합성 입력이며 실서비스의 변경 경합을 검증한 결과가 아니다.
응답과 실제 작업 종료를 나누는 일반 원칙은 202 이후 작업 완료 확인과 연결되지만, 여기서의 대상은 작업 상태가 아니라 목록의 페이지와 범위다. 부분 자료를 전체 주장으로 바꾸지 않는 판단은 출처와 결론의 지지 범위 확인에서도 이어진다.
자주 묻는 질문
페이지 크기를 최대로 하면 한 번만 받아도 되나요?
페이지 크기와 전체 결과 수는 별개다. 해당 엔드포인트의 상한과 다음 위치를 확인하고, 남은 페이지가 있으면 계약에 맞게 이어 읽는다.
Link 헤더가 없으면 항상 수집 완료인가요?
그 제품과 엔드포인트가 어떤 페이지 규칙을 쓰는지 먼저 확인한다. Link를 쓰지 않는 API도 있고, 응답 해석이나 요청 범위가 잘못됐을 수도 있다. 모든 API의 공통 종료 규칙으로 삼지 않는다.
총수와 저장 건수가 같으면 전체성을 확정하나요?
같은 범위·시점·집계 뜻인지 확인하고 ID 중복과 누락도 대조한다. 총수 일치는 유용한 신호지만, 서로 다른 ID가 바뀌어 들어온 경우까지 배제하는 증거는 아니다.
“API가 200이어도 전체 목록은 아니다: 페이지 끝과 수집 범위 확인”에 대한 1개의 생각