ADR 005: One generic core.PageIterator, no per-module wrappers
Status
Accepted
Context
tableapi and attachmentapi each shipped their own one-line pagination
entry point (tableapi.NewTablePageIterator, tableapi.NewDefaultTablePageIterator,
attachmentapi.NewAttachmentPageIterator) that did nothing but pre-bind the
module's Create...FromDiscriminatorValue factory to the generic
core.NewPageIterator[T]. No other collection-bearing module had one, so the
SDK had three ways to spell the same operation depending on which module you
were in (#490).
Alternatives considered:
- Give every collection-bearing module its own wrapper — rejected.
core.PageIteratorfollows responseLinkheaders, and not every ServiceNow collection endpoint emits them; aNewDefault<X>PageIteratorfor every module would advertise pagination an endpoint may not actually support. It also means auditing and maintaining N near-identical constructors forever, and the wrappers only help the default record type anyway — a caller using a custom type already passes a factory, at which point the wrapper saves nothing. - Generic-only — msgraph-sdk-go-core exposes exactly one generic
PageIterator; no generated per-module wrappers. Callers arriving from other Kiota SDKs already know this shape (ADR-003's tie-breaker rule).
Decision
Remove the three module-specific wrappers. core.NewPageIterator[T] is the
single, only documented pagination pattern:
iterator, err := core.NewPageIterator(response, client.GetRequestAdapter(),
tableapi.CreateTableRecordFromDiscriminatorValue)
Consequences
- Pros: one pattern to teach, document, and review, regardless of module; no risk of a wrapper implying pagination support an endpoint doesn't have.
- Cons: breaking removal of the three wrapper constructors — callers must migrate to the generic call. Landed pre-v2.0 for that reason.
- Rule for new modules: don't add a
New<X>PageIteratorwrapper for a new API module, even for symmetry withtableapi's old shape — that shape was removed deliberately, not left behind by omission. Document per-endpoint whether it actually emitsLinkheaders instead.