diff --git a/aep/general/0132/aep.md.j2 b/aep/general/0132/aep.md.j2 index 4f9f1653..a8bdd537 100644 --- a/aep/general/0132/aep.md.j2 +++ b/aep/general/0132/aep.md.j2 @@ -97,6 +97,7 @@ when the REST/JSON interface is used. `List` operations **must** return a page of results, with each individual result being a resource. + - The array of resources **must** be named `results` and contain resources with no additional wrapping. - The `string nextPageToken` field **must** be included in the list response @@ -112,6 +113,9 @@ result being a resource. - The response message **must** include a field corresponding to the resources being returned, named for the English plural term for the resource, and **should not** include any other repeated fields. +- The response message **may** include a `bool has_changed` field, to indicate + that the underlying data has changed since the `next_page_token` was + generated. - Fields providing metadata about the list request (such as `string next_page_token` or `int32 total_size`) **must** be included on the response (not as part of the resource itself). @@ -156,11 +160,11 @@ return `200 OK` with an empty results array, and not `404 Not Found`. ### Advanced operations -`List` methods **may** allow an extended set of functionality to allow a user to -specify the resources that are returned in a response. +`List` methods **may** allow an extended set of functionality to allow a user +to specify the resources that are returned in a response. -The following table summarizes the applicable AEPs, ordered by the precedence of -the operation on the results. +The following table summarizes the applicable AEPs, ordered by the precedence +of the operation on the results. | Operation | AEP | | ---------------------------- | --------------------------------- | diff --git a/aep/general/0158/aep.md.j2 b/aep/general/0158/aep.md.j2 index aafe36f8..44ec2a67 100644 --- a/aep/general/0158/aep.md.j2 +++ b/aep/general/0158/aep.md.j2 @@ -8,9 +8,9 @@ be paginated. ## Guidance -Methods returning collections of data **must** provide pagination _at the outset_, -as it is a [backwards-incompatible change](#backwards-compatibility) to add -pagination to an existing method. +Methods returning collections of data **must** provide pagination _at the +outset_, as it is a [backwards-incompatible change](#backwards-compatibility) +to add pagination to an existing method. {% tab proto %} @@ -50,8 +50,8 @@ message ListBooksResponse { } ``` -- The field containing pagination results **should** be the first field in - the message and have a field number of `1`. +- The field containing pagination results **should** be the first field in the + message and have a field number of `1`. {% tab oas %} @@ -60,39 +60,39 @@ message ListBooksResponse { {% endtabs %} - Request messages for collections **should** define an integer (`int32` for -protobuf) `max_page_size` field, allowing users to specify the maximum number of -results to return. + protobuf) `max_page_size` field, allowing users to specify the maximum number + of results to return. - If the user does not specify `max_page_size` (or specifies `0`), the API chooses an appropriate default, which the API **should** document. The API **must not** return an error. - - If the user specifies `max_page_size` greater than the maximum permitted by the - API, the API **should** coerce down to the maximum permitted page size. - - If the user specifies a negative value for `max_page_size`, the API **must** - send an `INVALID_ARGUMENT` error. + - If the user specifies `max_page_size` greater than the maximum permitted by + the API, the API **should** coerce down to the maximum permitted page size. + - If the user specifies a negative value for `max_page_size`, the API + **must** send an `INVALID_ARGUMENT` error. - The API **may** return fewer results than the number requested (including zero results), even if not at the end of the collection. - Request schemas for collections **should** define a `string page_token` field, allowing users to advance to the next page in the collection. - The `page_token` field **must not** be required. - - If the user changes the `max_page_size` in a request for subsequent pages, the - service **must** honor the new page size. + - If the user changes the `max_page_size` in a request for subsequent pages, + the service **must** honor the new page size. - The user is expected to keep all other arguments to the method the same; if any arguments are different, the API **should** send an `INVALID_ARGUMENT` error. - The response **must not** be a streaming response. -- Response messages for collections **must** define a - `string next_page_token` field, providing the user with a page token that may - be used to retrieve the next page. - - The field containing pagination results **must** be a repeated - field containing a list of resources constituting a single page of results. +- Response messages for collections **must** define a `string next_page_token` + field, providing the user with a page token that may be used to retrieve the + next page. + - The field containing pagination results **must** be a repeated field + containing a list of resources constituting a single page of results. - If the end of the collection has been reached, the `next_page_token` field **must** be empty. This is the _only_ way to communicate "end-of-collection" to users. - If the end of the collection has not been reached (or if the API can not determine in time), the API **must** provide a `next_page_token`. - Response messages for collections **may** provide an integer (`int32` for -protobuf) `total_size` field, providing the user with the total number of items -in the list. + protobuf) `totalSize` field, providing the user with the total number of + items in the list. - This total **may** be an estimate. If so, the API **should** explicitly document that. @@ -148,10 +148,30 @@ used. It is not necessary to document this behavior. **Note:** While a reasonable time may vary between APIs, a good rule of thumb is three days. +### Freshness + +Since a request with the same filter and `page_token` **should** return the +same results unless the page token has expired, items returned **may** have +been deleted or modified since the initial request, and paging through the list +**may** not include all current items. + +If the service is capable of detecting underlying changes in the listing since +a given `page_token` was generated: + +- The response **may** include a `has_changed` boolean. If this boolean is + supported but `false` or unset, the data **must** be up to date, and paging + through the list **must** include all current items. +- If no `has_changed` boolean is included, the API **may** expire the page + token. + +If the service is incapable of detecting such changes, for example if it is +using an in-memory storage mechanism without snapshots, it **may** return stale +data or phantom reads with no indication. + ### Backwards compatibility -Adding pagination to an existing method is a backwards-incompatible change. This -may seem strange; adding fields to proto messages is generally backwards +Adding pagination to an existing method is a backwards-incompatible change. +This may seem strange; adding fields to proto messages is generally backwards compatible. However, this change is _behaviorally_ incompatible. Consider a user whose collection has 75 resources, and who has already written @@ -174,4 +194,4 @@ paginate) is reasonable for initially-small collections. ## Changelog -- **2024-04-14**: Imported from https://google.aip.dev/158. \ No newline at end of file +- **2024-04-14**: Imported from https://google.aip.dev/158.