From 1702e7d9a17b507ff7bf0ab73cb0533aad3b3871 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 25 Sep 2026 13:18:13 -0500 Subject: [PATCH 1/5] Updates to contract and API.html now that the pagination work is more stable --- openapi/contracts/core-provider.openapi.yaml | 104 ++++++++++++++++++- public/API.html | 13 ++- 2 files changed, 109 insertions(+), 8 deletions(-) diff --git a/openapi/contracts/core-provider.openapi.yaml b/openapi/contracts/core-provider.openapi.yaml index 6dec6e16..29418c7c 100644 --- a/openapi/contracts/core-provider.openapi.yaml +++ b/openapi/contracts/core-provider.openapi.yaml @@ -211,6 +211,9 @@ paths: post: summary: Query objects operationId: queryObjects + parameters: + - $ref: '#/components/parameters/PageLimit' + - $ref: '#/components/parameters/PageSkip' requestBody: required: true content: @@ -225,12 +228,20 @@ paths: headers: Link: $ref: '#/components/headers/NextPageLink' + Pagination-Limit: + $ref: '#/components/headers/PaginationLimit' + Pagination-Skip: + $ref: '#/components/headers/PaginationSkip' + Pagination-Limit-Max: + $ref: '#/components/headers/PaginationLimitMax' + Pagination-Skip-Max: + $ref: '#/components/headers/PaginationSkipMax' content: application/json: schema: $ref: '#/components/schemas/GenericArray' '400': - $ref: '#/components/responses/BadRequest' + $ref: '#/components/responses/PageBadRequest' '413': $ref: '#/components/responses/PayloadTooLarge' '415': @@ -239,6 +250,9 @@ paths: post: summary: Search objects by keywords operationId: searchObjects + parameters: + - $ref: '#/components/parameters/PageLimit' + - $ref: '#/components/parameters/PageSkip' requestBody: required: true content: @@ -256,12 +270,20 @@ paths: headers: Link: $ref: '#/components/headers/NextPageLink' + Pagination-Limit: + $ref: '#/components/headers/PaginationLimit' + Pagination-Skip: + $ref: '#/components/headers/PaginationSkip' + Pagination-Limit-Max: + $ref: '#/components/headers/PaginationLimitMax' + Pagination-Skip-Max: + $ref: '#/components/headers/PaginationSkipMax' content: application/json: schema: $ref: '#/components/schemas/GenericArray' '400': - $ref: '#/components/responses/BadRequest' + $ref: '#/components/responses/PageBadRequest' '413': $ref: '#/components/responses/PayloadTooLarge' '415': @@ -270,6 +292,9 @@ paths: post: summary: Search objects by phrase operationId: searchObjectsByPhrase + parameters: + - $ref: '#/components/parameters/PageLimit' + - $ref: '#/components/parameters/PageSkip' requestBody: required: true content: @@ -287,12 +312,20 @@ paths: headers: Link: $ref: '#/components/headers/NextPageLink' + Pagination-Limit: + $ref: '#/components/headers/PaginationLimit' + Pagination-Skip: + $ref: '#/components/headers/PaginationSkip' + Pagination-Limit-Max: + $ref: '#/components/headers/PaginationLimitMax' + Pagination-Skip-Max: + $ref: '#/components/headers/PaginationSkipMax' content: application/json: schema: $ref: '#/components/schemas/GenericArray' '400': - $ref: '#/components/responses/BadRequest' + $ref: '#/components/responses/PageBadRequest' '413': $ref: '#/components/responses/PayloadTooLarge' '415': @@ -705,6 +738,33 @@ components: example: >- ; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json", ; rel="next" + PaginationLimit: + description: >- + The 'limit' applied to this page, after any reduction to the maximum. Read it rather than + assuming the requested 'limit' was served. + schema: + type: integer + minimum: 1 + PaginationSkip: + description: >- + The 'skip' applied to this page. + schema: + type: integer + minimum: 0 + PaginationLimitMax: + description: >- + The largest 'limit' served. A larger 'limit' is reduced to it. + schema: + type: integer + minimum: 1 + example: 500 + PaginationSkipMax: + description: >- + The largest 'skip' accepted. A larger 'skip' is a 400. + schema: + type: integer + minimum: 1 + example: 100000 parameters: ObjectId: in: path @@ -726,6 +786,34 @@ components: description: Only expand with Annotations attributed to this creator. schema: type: string + PageLimit: + in: query + name: limit + required: false + description: >- + How many records to serve, as a whole number in plain decimal digits. The maximum is 500, and + 'Pagination-Limit-Max' reports the maximum in effect. A larger 'limit' is reduced to the + maximum rather than rejected, and 'Pagination-Limit' reports what was applied. A value that + is not plain decimal digits, is 0, or is sent more than once is a 400. + schema: + type: integer + minimum: 1 + default: 100 + PageSkip: + in: query + name: skip + required: false + description: >- + How many records to pass over before the page starts, as a whole number in plain decimal + digits. The maximum is 100000, and 'Pagination-Skip-Max' reports the maximum in effect. A + larger 'skip' is a 400 rather than being reduced, because every page past the maximum would + repeat the page at it. A value that is not plain decimal digits, or is sent more than once, + is a 400 too. + schema: + type: integer + minimum: 0 + maximum: 100000 + default: 0 schemas: GenericObject: type: object @@ -737,6 +825,16 @@ components: responses: BadRequest: description: Bad request — the request body was missing, empty, or otherwise invalid. + PageBadRequest: + description: >- + Bad request — the request body was missing, empty, or otherwise invalid, or the 'limit' or + 'skip' URL parameter was. When 'limit' or 'skip' caused it, the response still reports both + maximums. + headers: + Pagination-Limit-Max: + $ref: '#/components/headers/PaginationLimitMax' + Pagination-Skip-Max: + $ref: '#/components/headers/PaginationSkipMax' Unauthorized: description: Unauthorized — missing, malformed, or invalid bearer token. Forbidden: diff --git a/public/API.html b/public/API.html index d8a34f82..21c1fe7f 100644 --- a/public/API.html +++ b/public/API.html @@ -490,7 +490,7 @@

Custom Query

- /query?limit=10&skip=0 + /query?limit=100&skip=0 {JSON} 200 [{JSON}] @@ -505,7 +505,7 @@

Custom Query

This simple format will be made more complex in the future, but should serve the basic needs as it is. RERUM will test for property matches. By default, this is limited to 100 records in the response to guard against unreasonable queries. To allow for more records in the response one can add the URL parameter limit to the query requests. If you expect the query request will have a very large response with many objects, your application should use a paged query that follows the rel="next" link in each response's Link header until there is none. You will see an example of this below. -

A limit above the maximum of 500 is not an error. It is reduced to 500, and the response says so — see Pagination parameters. Read the applied value from the Pagination-Limit response header rather than assuming you received everything you asked for.

+

A limit above the maximum of 500 is not an error. It is reduced to 500, and the response says so — see Pagination parameters. Read the applied value from the Pagination-Limit response header rather than assuming you received everything you asked for. A skip above the maximum of 100000 is not reduced. It is a 400.

Non-Paged Query Javascript Example
@@ -579,7 +579,7 @@

Custom Query

Pagination parameters

- limit and skip are URL parameters shared by Custom Query, Text Search, and Phrase Search. Both must be whole numbers written in plain decimal digits. Anything else is a 400. + limit and skip are URL parameters shared by Custom Query, Text Search, and Phrase Search. Both must be whole numbers written in plain decimal digits. Anything else is a 400, and so is sending either one more than once.

@@ -605,6 +605,9 @@

Pagination parameters

+

+ Only a parameter named exactly limit or skip is read. A bracketed parameter such as ?limit[a]=5 arrives under the name limit[a], so RERUM cannot tell it apart from leaving limit out, and the default applies. If you build paging URLs programmatically, check Pagination-Limit. +

Every paged response reports what was applied and what the maximums are, so a client can configure itself from any single response. These headers are readable cross-origin.

@@ -676,7 +679,7 @@

To allow for more records in the response one can add the URL parameter limit to the search requests. If you expect the search request will have a very large response with many objects, your application should use a paged search that follows the rel="next" link in each response's Link header until there is none. You will see an example of this below. -

A limit above the maximum of 500 is reduced to 500, and the response says so — see Pagination parameters. Read the applied value from the Pagination-Limit response header rather than assuming you received everything you asked for.

+

A limit above the maximum of 500 is reduced to 500, and the response says so — see Pagination parameters. Read the applied value from the Pagination-Limit response header rather than assuming you received everything you asked for. A skip above the maximum of 100000 is not reduced. It is a 400.

Search behavior: @@ -825,7 +828,7 @@

To allow for more records in the response one can add the URL parameter limit to the search requests. If you expect the search request will have a very large response with many objects, your application should use a paged search that follows the rel="next" link in each response's Link header until there is none. You will see an example of this below. -

A limit above the maximum of 500 is reduced to 500, and the response says so — see Pagination parameters. Read the applied value from the Pagination-Limit response header rather than assuming you received everything you asked for.

+

A limit above the maximum of 500 is reduced to 500, and the response says so — see Pagination parameters. Read the applied value from the Pagination-Limit response header rather than assuming you received everything you asked for. A skip above the maximum of 100000 is not reduced. It is a 400.

Search behavior: From 9cd675b3fe728c57dd43eee70e2f93c8b724b870 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 25 Sep 2026 13:28:06 -0500 Subject: [PATCH 2/5] simplify --- openapi/contracts/core-provider.openapi.yaml | 11 +++-------- public/API.html | 3 --- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/openapi/contracts/core-provider.openapi.yaml b/openapi/contracts/core-provider.openapi.yaml index 29418c7c..6ff7c0fd 100644 --- a/openapi/contracts/core-provider.openapi.yaml +++ b/openapi/contracts/core-provider.openapi.yaml @@ -791,10 +791,8 @@ components: name: limit required: false description: >- - How many records to serve, as a whole number in plain decimal digits. The maximum is 500, and - 'Pagination-Limit-Max' reports the maximum in effect. A larger 'limit' is reduced to the - maximum rather than rejected, and 'Pagination-Limit' reports what was applied. A value that - is not plain decimal digits, is 0, or is sent more than once is a 400. + How many records to serve, as a whole number in plain decimal digits. A larger 'limit' + is reduced to the maximum rather than rejected. schema: type: integer minimum: 1 @@ -805,10 +803,7 @@ components: required: false description: >- How many records to pass over before the page starts, as a whole number in plain decimal - digits. The maximum is 100000, and 'Pagination-Skip-Max' reports the maximum in effect. A - larger 'skip' is a 400 rather than being reduced, because every page past the maximum would - repeat the page at it. A value that is not plain decimal digits, or is sent more than once, - is a 400 too. + digits. A 'skip' beyond 100000 is rejected with a 400. schema: type: integer minimum: 0 diff --git a/public/API.html b/public/API.html index 21c1fe7f..5c7aac3b 100644 --- a/public/API.html +++ b/public/API.html @@ -605,9 +605,6 @@

Pagination parameters

-

- Only a parameter named exactly limit or skip is read. A bracketed parameter such as ?limit[a]=5 arrives under the name limit[a], so RERUM cannot tell it apart from leaving limit out, and the default applies. If you build paging URLs programmatically, check Pagination-Limit. -

Every paged response reports what was applied and what the maximums are, so a client can configure itself from any single response. These headers are readable cross-origin.

From 1c3e3297427caaa6b01a2202d0b65f8d7cda8df5 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 25 Sep 2026 13:37:49 -0500 Subject: [PATCH 3/5] merge it --- openapi/contracts/core-provider.openapi.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi/contracts/core-provider.openapi.yaml b/openapi/contracts/core-provider.openapi.yaml index 6ff7c0fd..1ad6d27e 100644 --- a/openapi/contracts/core-provider.openapi.yaml +++ b/openapi/contracts/core-provider.openapi.yaml @@ -791,8 +791,8 @@ components: name: limit required: false description: >- - How many records to serve, as a whole number in plain decimal digits. A larger 'limit' - is reduced to the maximum rather than rejected. + How many records to serve, as a whole number in plain decimal digits. A 'limit' + larger than 500 is reduced to 500 rather than rejected. schema: type: integer minimum: 1 From 12301af2f5a54aeeab8358ec63a25a8f6c5707e2 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 25 Sep 2026 13:41:38 -0500 Subject: [PATCH 4/5] merge --- openapi/contracts/core-provider.openapi.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openapi/contracts/core-provider.openapi.yaml b/openapi/contracts/core-provider.openapi.yaml index 1ad6d27e..48643015 100644 --- a/openapi/contracts/core-provider.openapi.yaml +++ b/openapi/contracts/core-provider.openapi.yaml @@ -822,9 +822,8 @@ components: description: Bad request — the request body was missing, empty, or otherwise invalid. PageBadRequest: description: >- - Bad request — the request body was missing, empty, or otherwise invalid, or the 'limit' or - 'skip' URL parameter was. When 'limit' or 'skip' caused it, the response still reports both - maximums. + The request body was malformed. It could also mean the 'limit' or 'skip' URL parameter + was malformed. headers: Pagination-Limit-Max: $ref: '#/components/headers/PaginationLimitMax' From 491cb398836282ff6a18b7f71cde681ecabad68f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 25 Sep 2026 13:42:53 -0500 Subject: [PATCH 5/5] merge --- openapi/contracts/core-provider.openapi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi/contracts/core-provider.openapi.yaml b/openapi/contracts/core-provider.openapi.yaml index 48643015..84af914c 100644 --- a/openapi/contracts/core-provider.openapi.yaml +++ b/openapi/contracts/core-provider.openapi.yaml @@ -823,7 +823,7 @@ components: PageBadRequest: description: >- The request body was malformed. It could also mean the 'limit' or 'skip' URL parameter - was malformed. + was malformed or beyond the maximum. headers: Pagination-Limit-Max: $ref: '#/components/headers/PaginationLimitMax'