@@ -10,8 +10,9 @@ placement:
1010# Unreachable resources
1111
1212Occasionally, a user may ask for a list of resources, and some set of resources
13- in the list are temporarily unavailable. For example, a user may ask to list
14- resources across multiple parent locations, but one of those locations is
13+ in the list are temporarily unavailable. The most typical use case is while
14+ supporting [ Reading Across Collections] [ aip-159 ] . For example, a user may ask to
15+ list resources across multiple parent locations, but one of those locations is
1516temporarily unreachable. In this situation, it is still desirable to provide
1617the user with all the available resources, while indicating that something is
1718missing.
@@ -32,7 +33,9 @@ message ListBooksResponse {
3233 string next_page_token = 2;
3334
3435 // Unreachable resources.
35- repeated string unreachable = 3;
36+ repeated string unreachable = 3 [
37+ (google.api.field_behavior) = UNORDERED_LIST
38+ ];
3639}
3740```
3841
@@ -72,10 +75,15 @@ message ListBooksResponse {
7275 resource's name e.g.
7376 ` "projects/example123/locations/europe-west2/instances/example456" ` will
7477 both appear in ` unreachable ` .
78+ - The ` unreachable ` field ** must not** have semantically meaningful ordering or
79+ structure within the list. Put differently, ` unreachable ` ** must** be an
80+ unordered list.
81+ - As such, the ` unreachable ` field ** must** be annotated with ` UNORDERED_LIST `
82+ field behavior (see [ AIP-203] [ unordered ] ).
7583
7684[ aip-122 ] : ./0122.md
7785[ aip-160 ] : ./0160.md
78-
86+ [ unordered ] : ./0203.md#unordered-list
7987
8088** Important:** If a single unreachable location or resource prevents returning
8189any data by definition (for example, a list request for a single publisher
@@ -84,36 +92,49 @@ request with an error.
8492
8593### Pagination
8694
87- When paginating over a list, it is likely that the service will not know that
88- there are unreachable parents or resources initially. Further, parents may
89- alternate between being available and unavailable in unpredictable ways
90- throughout the process of listing all the requested resources.
91-
92- These facts lead to the following guidance:
93-
94- - The response ** must** provide any outstanding unreachable locations or
95- resources in the ` unreachable ` field on pages _ following_ the final page that
96- contains a resource.
97- - The response ** should not** include both requested data and unreachable
98- resources on the same page.
99- - For example, if there are two pages of books and one unavailable
100- publisher, there should be three pages total: first the two pages of
101- books, and then a final page with no books and the unavailable publisher.
102- - If the number of unreachable resources to list is very large, the response
103- ** should** honor the ` page_size ` field in the same way as for resources. In
104- this case, all pages with requested information ** should** precede all
105- pages with unavailable resources or locations.
106- - The final page's ` unreachable ` field ** must** _ only_ include resources or
107- parents that were partially provided (or missing completely) across the
108- entirety of the pagination process.
109- - For example, if a parent or resource was unreachable at the beginning of
110- pagination and it became reachable again and the entire set of previously
111- unreachable data was provided to the user on any page, the ` unreachable `
112- field ** must not** include the intermittently-unreachable parent or
113- resource.
114- - On the other hand, if only _ some_ of the resources for a given parent are
115- provided during such an incident as described above, the parent or
116- resource ** must** be included in the ` unreachable ` field.
95+ While preparing a page of results to fulfill a page fetch RPC e.g. an
96+ [ AIP-132] [ aip-132 ] Standard List call, if the service encounters any unreachable
97+ resources or collections they ** must** do the following:
98+
99+ - Include the resource name for the unreachable resource in the ` unreachable `
100+ response field.
101+ - The resource name ** must** be the most appropriately scoped for the
102+ unreachable resource or collection.
103+ - For example, if a specific zone within a region is unreachable, the
104+ unreachable resource name would be a zonal Location e.g.
105+ ` projects/example/locations/us-west1-a ` , but if an entire region is
106+ unreachable, the resource name would be a regional Location e.g.
107+ ` projects/example/locations/us-west1 ` .
108+ - The resource name ** must** be included, regardless of restrictive paging
109+ parameters e.g. ` order_by ` , when it is identified as unreachable.
110+ - Populate results that were previously considered unreachable on a following
111+ page if their availability is restored and the paging parameters allow for
112+ their inclusion.
113+ - Determining inclusion eligibility based on paging parameters also includes
114+ any documented default ordering behavior in the absence of user-specified
115+ ordering in the request.
116+ - For example, if region ` projects/example/locations/us-west1 ` was unavailable
117+ in the first page of an ordered paging call, and including its resources
118+ would violate the ordering, those out-of-order resources are not included in
119+ the following page.
120+ - Similarly, if the same exact request is made, and resources previously
121+ considered unreachable are available again, they ** must** be populated,
122+ within the constraints of the paging parameters.
123+ - Limit the number of unreachable resource names returned in a given response
124+ if, even after up-scoping the unreachable resource name, the number of
125+ unreachable resource names exceeds a documented maximum.
126+ - This maximum ** must** be documented in the ` unreachable ` field comments
127+ directly.
128+ - This is independent of the ` page_size ` set by the caller.
129+
130+ #### Retaining previous behavior
131+
132+ Services ** may** continue with previously implemented ` unreachable ` pagination
133+ behavior where changing it would induce an incompatible change as per
134+ [ AIP-180] [ aip-180 ] , but ** must** document said behavior on the ` unreachable `
135+ field(s) directly.
136+
137+ [ aip-180 ] : ./0180.md
117138
118139### Adopting partial succcess
119140
@@ -153,7 +174,9 @@ message ListBooksResponse {
153174 // Unreachable resources. Populated when the request opts into
154175 // `return_partial_success` and reading across collections e.g. when
155176 // attempting to list all resources across all supported locations.
156- repeated string unreachable = 3;
177+ repeated string unreachable = 3 [
178+ (google.api.field_behavior) = UNORDERED_LIST
179+ ];
157180}
158181```
159182
@@ -191,6 +214,25 @@ checks and system state resolution on at time of request, rather than by
191214shoehorning potentially privileged or stale information into the broader list
192215call it was unreachable for.
193216
217+ ### Unordered ` unreachable ` contents
218+
219+ It is important for broad API consistency that the contents of ` unreachable ` not
220+ have a specific or order semantic structure. If each API baked a specific
221+ ordering into a standard field, no single implementation, client or server side,
222+ would be correct.
223+
224+ ### Per page ` unreachable ` resources
225+
226+ Populating ` unreachable ` resources on a per page basis allows end users to
227+ identify immediately when a page is incomplete, rather than _ after_ paging
228+ through all results. Paging to completion is not guaranteed, so it is important
229+ to communicate as soon as possible when there are unreachable resource missing
230+ from a given page. Furthermore, it allows users to identify when there is a
231+ potential issue that they need to account for in subsequent calls. Finally,
232+ retaining unreachable resources until the end of paging results requires
233+ services to retain the state for what should be indepedent and fully isolated
234+ API calls.
235+
194236### Using request field to opt-in
195237
196238Introducing a new request field as means of opting into the partial success
@@ -221,13 +263,25 @@ resources if there was an issue, but not getting any, thus falsely assuming
221263everything was retrieved. This aligns with guidance herein that suggests failing
222264requests that cannot be fulfilled preemptively.
223265
266+ ## History
267+
268+ ### Pagination guidance
269+
270+ The original guidance for how to populate the ` unreachable ` field revolved
271+ around consuming the contents as if they were the paged results. This meant that
272+ paged resources and unreachable resources couldn't be returned in the same
273+ response i.e. page, and users needed to completely page through all results
274+ in order to see if any were unreachable. See the Rationale section for the
275+ reasoning around the changes.
276+
224277## Further reading
225278
226279- For listing across collections, see [ AIP-159] [ ] .
227280
228281## Changelog
229282
230283- ** 2024-07-29** : Reformat guidance, add explicit resource name format
284+ - ** 2024-07-26** : Change pagination guidance.
231285 requirement.
232286- ** 2024-07-19** : Add guidance for brownfield adoption of partial success.
233287
0 commit comments