OpenAPI pagination metadata: no standard for next/prev link representation
0 reputation · 23 May 2021, 00:29 UTC
0 reputation · 23 May 2021, 00:29 UTC
The OpenAPI Specification does not define a model for pagination metadata. Service designers must decide how to embed next, prev, first, and last links, as well as total count and page size, in the response body.
Constraints include tooling compatibility (Swagger UI, ReDoc, OpenAPI Generator), privacy (exposing total counts may reveal data volume), and consistency across multiple APIs. Vendor extensions such as x-pagination exist but are not governed by the core spec and may break client generation.
To move forward, we need a decision on a shared pagination contract that balances tooling support, privacy, and developer ergonomics.
links.next, links.prev) across services to avoid duplicated schema definitions?35275 reputation · 23 May 2021, 07:27 UTC
Because the OpenAPI Specification (OAS) does not provide a native keyword or object for pagination, the only way to ensure tooling compatibility and consistency is to define a custom reusable schema in the components/schemas section. This ensures that OpenAPI Generator and other tools treat the pagination metadata as a first-class typed object rather than an arbitrary map.
To maximize compatibility with Swagger UI and ReDoc without relying on vendor extensions, use a wrapper object. This avoids polluting the resource array and maintains type safety in strongly typed client languages.
components:
schemas:
PaginationMetadata:
type: object
properties:
totalCount:
type: integer
description: Total number of resources available (optional).
pageSize:
type: integer
currentPage:
type: integer
links:
type: object
properties:
next: { type: string, format: uri }
prev: { type: string, format: uri }
first: { type: string, format: uri }
last: { type: string, format: uri }
PaginatedResponse:
type: object
properties:
data:
type: array
items: { $ref: '#/components/schemas/Resource' }
pagination:
$ref: '#/components/schemas/PaginationMetadata'
Total Counts: To mitigate privacy concerns (such as revealing the exact size of a user database), totalCount should be optional. If omitted, clients can rely on the presence of the links.next URI to determine if more data exists, which is the standard approach for cursor-based pagination.
Link Representation: Standardizing links as a nested links object (following HATEOAS principles) is the most scalable method. By defining this as a shared component, you avoid duplicating the schema across every list endpoint in your API.
PaginationMetadata class in your target language (e.g., Java, TypeScript) using OpenAPI Generator.links.next value is a full URI or a relative path that the client can resolve against the base URL.Diagnostic Detail Needed: Are you utilizing offset-based pagination (page numbers) or cursor-based pagination (opaque tokens)? This determines whether currentPage and totalCount are functionally useful or should be replaced by a nextCursor string.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 23 May 2021, 04:09 UTC
OpenAPI does not define a pagination model, but it does provide a spec-level way to document navigational links without vendor extensions.
In OpenAPI 3.0 and 3.1 an Operation Response can define a links object with runtime expressions for next, prev, first and last. This describes HATEOAS navigation at the operation level and keeps the response body schema focused on the resource array, which helps codegen stay clean.
If pagination is modeled in the body, a reusable component schema is the consistent approach. For RFC 5988 Link header pagination, document the header in responses[].headers.link rather than in the body schema, a frequent modeling error. Links evaluation and tooling support differ between OpenAPI 3.0 and 3.1, so verify generated clients surface the relations as intended.