Describe the three pagination shapes, and give new endpoints one - #322
Merged
Conversation
api-overview.md said list endpoints take limit/offset, default 50 and max 200, with a matching envelope. That is true of 8 endpoints. Fifteen take page/page_size and six take page/size, and defaults and maxima vary inside each group, so anyone writing a client against the page got it wrong for most of the API. The page now states all three, which endpoints use each, and that they will converge at 1.0.0 rather than across minors. PageParams and Page give new endpoints one shape so the count stops growing. Existing endpoints are left alone: a compatibility layer accepting both spellings would promise more stability than a pre-1.0 project offers and leave two paths to keep correct.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
api-overview.mddocumented a single pagination contract:limit/offset, default 50, max 200, with an envelope carryinglimitandoffsetback. Counted from the published OpenAPI schema, that describes 8 endpoints. Fifteen takepage/page_sizeand six takepage/size, and both groups returnpage/page_sizein the body regardless of which query parameters they accept. Defaults and maxima vary inside each group too:limitmaxes at 200 on the inventory endpoints and 500 on the per-project ones;sizedefaults to 20, except 25 on search and 100 on the source tree. Anyone writing a client or an export script from that page got it right for a fifth of the API and silently wrong for the rest.The page now says there are three, which endpoints use each, what each returns, and that the values vary so they should not be hard-coded. It also says why three exist and what happens next, because a reader who finds this needs to know whether it is about to change under them. The plan called for
sortto be corrected as well; it is accurate as written, accepted by ten endpoints, so it is left alone.PageParamsandPageincore/pagination.pyare the half that stops the count growing: one query-parameter spelling and one envelope for endpoints written from here on, sitting next to thePAGE_MAXbound that module already owns. The batch endpoints in the bulk-onboarding unit are the first callers.Existing endpoints are not touched, and that is the substantive decision. The plan called for accepting both spellings everywhere with
DeprecationandSunsetheaders, retiring the old one a minor later. I did not do that.SECURITY.mdsays a pre-1.0 minor may change the HTTP API; a compatibility layer would promise more stability than that in code while the documentation promises less, and would leave two paths to keep correct in every list endpoint meanwhile.Deprecation/Sunsetare how a stable API announces a retreat, and attaching them to an API that has said it is not stable yet overstates the guarantee. Converging the 29 belongs at 1.0.0, where a caller expects one breaking change instead of a series of small ones, and it is on the roadmap under a new "For 1.0.0" heading.The contract tests drive the dependency through a real FastAPI app rather than instantiating the dataclass, because the failure worth catching is the wiring: parameters that never reach the query string, or bounds that never reach the schema, still look right in a constructor call. They assert the spelling from the generated schema, that bounds are published and not merely enforced, that
pageis 1-based (page 3 of 25 starts at row 50, an off-by-one no single response would reveal), and that out-of-range is a 422 rather than a silent clamp. I mutated the module three ways to check they bite:offsetoff by one page,page_sizerenamed tosize, and the cap raised tenfold; they caught 1, 9 and 2 tests respectively. Two further tests pin the endpoint counts in the documentation against the schema, so a new endpoint on an old spelling fails here rather than quietly making the page wrong again, and a fourth spelling is caught separately since the count table would not see it.Verified locally: those 14 tests, the mutations above, ruff, mypy over 836 files, ko-style, em-dash,
docs-uatlint, a docs-site production build with no new broken anchors (the#openapilink I first wrote did not resolve; the target heading now carries an explicit{#openapi-schema}anchor in both languages), and the backend unit suite at 6897 passed. Twotest_admin_team_servicefailures were 736 organizations accumulated in a database my earlier runs shared; both pass on a fresh one.