ADR 013: Paging headers captured and included in collection response
Status
In Progress
Context
The ServiceNow SDK currently uses a generic core.PageIterator (per ADR 005) that consumes Link headers from responses to enable cursor-based pagination. However, users must explicitly call the iterator and manage the pagination loop themselves. There is no guarantee that the Link headers will be preserved or that the response object itself exposes pagination metadata, forcing each consumer to reimplement header extraction and pagination logic.
Decision
We will modify the collection response pattern so that pagination Link headers are automatically captured and included as a first-class field in every collection response type. Specifically:
- Response envelope: All
core.ServiceNowCollectionResponse[T](and equivalent response types) will include aPagingfield of type*PagingInfothat extracts and stores theLinkheader values (next,prev,first,last) from the HTTP response. - Automatic extraction: The
PagingInfois populated during deserialization — users do not need to manually parse headers or pass them to a separate iterator constructor. - Backward compatibility: The
core.PageIteratorremains available for callers who want explicit pagination control, but the default response now provides the headers immediately. - Per-type paging struct: A shared
internal/paging.godefinesPagingInfowithNext,Prev,First,Laststring fields (all pointers to distinguish "not present" from "empty").
Alternatives considered:
- Leave headers on the wire only: Users must extract
Linkheaders themselves via the request adapter or HTTP client — shifts all pagination logic to the consumer and increases friction for new users. - One generic iterator only (ADR 005): Already in place; does not solve the problem of headers not being surfaced on the response object itself.
- Per-module paging wrappers: Rejected by ADR 005 — creates N near-identical constructors and does not generalize across modules.
Consequences
- Provenance: Pagination metadata is always available on the response, eliminating a common source of consumer-side bugs and reducing boilerplate.
- Usability: New users can access
nextpage URLs directly from the response without needing to understand or usecore.PageIterator— the SDK handles header extraction. - Tooling: HTTP clients and intermediate proxies can still read the
Linkheaders from the raw response; the SDK does not strip them. - Maintenance: Adds a small shared struct (
PagingInfo) and deserialization logic to thecorepackage; the change is isolated and does not require per-module updates since all collection responses already embedcore.ServiceNowCollectionResponse[T]. - Interaction with PageIterator: The
core.PageIteratorwill continue to work as before, but now it can initialize from thePagingInfoembedded in the response, making the two mechanisms complementary rather than contradictory.