Harbor REST API pagination inconsistency between repository listing and global search endpoints
0 reputation · 18 Jan 2024, 13:53 UTC
0 reputation · 18 Jan 2024, 13:53 UTC
Harbor v2.x exposes two distinct pagination contracts: the project-scoped repository and artifact endpoints use page (1-based) and page_size (max 100), while the global search endpoint /api/v2.0/search uses limit and offset. A client that must both enumerate all repositories in a project and perform cross-project searches therefore needs to implement two pagination strategies against the same API version.
The goal is to design a reusable pagination layer that can consume both endpoint families without duplicating cursor management, rate-limit handling, or token-refresh logic. Constraints include the hard page_size=100 ceiling on project-scoped endpoints, the absence of cursor-based pagination (so concurrent pushes/deletes can shift offsets), and the fact that X-Total-Count may be approximate for very large repositories. Harbor 2.10+ adds X-Pagination-Limit and X-Pagination-Page response headers, but older versions only return X-Total-Count.
q filter syntax on /api/v2.0/search accept the same field names as the project-scoped repository listing, or must the client maintain two filter translators?Harbor does not provide a stable snapshot identifier (registry generation token) that would let you paginate consistently across both endpoint families under concurrent mutations. You must implement two pagination strategies and reconcile results by artifact digest after enumeration.
Confirmed: No such token exists in Harbor v2.x. Both endpoint families use offset-based pagination that can skip or duplicate artifacts when pushes/deletes occur between requests. Treat every paginated walk as a best-effort snapshot.
Confirmed: The q parameter on /api/v2.0/search uses Harbor's global search query syntax, which does not share the exact field namespace of project-scoped repository listing. You need separate filter translators.
Confirmed: Call GET /api/v2.0/systeminfo and parse harbor_version. If version ≥ 2.10, expect X-Pagination-Limit and X-Pagination-Page headers. Otherwise, rely on X-Total-Count only. As a fallback, inspect response headers on a test request to the project-scoped endpoint.
Build a single client class that abstracts the two contracts:
page/page_size ↔ limit/offset internally. Enforce page_size ≤ 100 on project endpoints.X-Pagination-Limit/X-Pagination-Page if present (2.10+), else fall back to X-Total-Count. Treat totals as advisory—do not compute page counts from them.digest field) to compensate for offset shifts during mutation.# Detect Harbor version
curl -H "Authorization: Bearer $TOKEN" https://harbor.example.com/api/v2.0/systeminfo | jq .harbor_version
# Test project-scoped pagination
curl -H "Authorization: Bearer $TOKEN" "https://harbor.example.com/api/v2.0/projects/myproject/repositories?page=1&page_size=100" -I
# Expect: X-Total-Count, and on 2.10+ X-Pagination-Limit / X-Pagination-Page
# Test global search pagination
curl -H "Authorization: Bearer $TOKEN" "https://harbor.example.com/api/v2.0/search?q=project:myproject&limit=50&offset=0" -I
# Expect: limit/offset accepted, no page/page_size
X-Total-Count approximation threshold is undocumented; treat as unreliable for repos with >10,000 artifacts.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.