@@ -91,8 +91,97 @@ These facts lead to the following guidance:
9191 provided during such an incident as described above, the parent or
9292 resource ** must** be included in the ` unreachable ` field.
9393
94+ ### Adopting partial succcess
95+
96+ In order for an existing API that has a default behavior * differing* from the
97+ aforementioned guidance i.e. the API call returns an error status instead of a
98+ partial result, to adopt the ` unreachable ` pattern the API ** must** do the
99+ following:
100+
101+ * the default behavior ** must** be retained to avoid incompatible behavioral
102+ changes
103+ * For example, if the default behavior is to return an error if any location
104+ is unreachable, that default behavior ** must** be retained.
105+ * the request message ** must** have a ` bool return_partial_success ` field
106+ * the response message ** must** have the standard
107+ ` repeated string unreachable ` field
108+ * the two aforementioned fields ** must** be added simultaneously
109+
110+ When the ` bool return_partial_success ` field is set to ` true ` in a request, the
111+ API ** must** behave as described in the aforementioned guidance with regards to
112+ populating the ` repeated string unreachable ` response field.
113+
114+ ``` proto
115+ message ListBooksRequest {
116+ // Standard List request fields...
117+
118+ // Setting this field to `true` will opt the request into returning the
119+ // resources that are reachable, and into including the names of those that
120+ // were unreachable in the [ListBooksResponse.unreachable] field. This can
121+ // only be `true` when reading across collections e.g. when `parent` is set to
122+ // `"projects/example/locations/-"`.
123+ bool return_partial_success = 4;
124+ }
125+
126+ message ListBooksResponse {
127+ // Standard List Response fields...
128+
129+ // Unreachable resources. Populated when the request opts into
130+ // `return_partial_success` and reading across collections e.g. when
131+ // attempting to list all resources across all supported locations.
132+ repeated string unreachable = 3;
133+ }
134+ ```
135+
136+ #### Partial success granularity
137+
138+ If the ` bool return_partial_success ` field is set to ` true ` in a request that is
139+ scoped beyond the supported granualirty of the API's ability to reasonably
140+ report unreachable resources, the API ** should** return an ` INVALID_ARGUMENT `
141+ error with details explaining the issue. For example, if the API only supports
142+ ` return_partial_success ` when [ Reading Across Collections] [ aip159 ] , it returns
143+ an ` INVALID_ARGUMENT ` error when given a request scoped to a specific parent
144+ resource collection. The supported granularity ** must** be documented on the
145+ ` return_partial_success ` field.
146+
147+ ## Rationale
148+
149+ ### Using request field to opt-in
150+
151+ Introducing a new request field as means of opting into the partial success
152+ behavior is the best way to communicate user intent while keeping the
153+ default behavior backwards compatible. The alternative, changing the default
154+ behavior with the introduction of the ` unreachable ` response field, presents
155+ a backwards incompatible change. Users that previously expected failure when any
156+ resource was unreachable, assume the successful response means all resources
157+ are accounted for in the response.
158+
159+ ### Introducing fields simultaneously
160+
161+ Introducing the request and response fields simultaneously is to prevent an
162+ invalid intermediate state that is presented by only adding one or the other. If
163+ only ` unreachable ` is added, then it could be assumed that it being empty means
164+ all resources were returned when that may not be true. If only
165+ ` return_partial_success ` is added, then the user wouldn't have a means of
166+ knowing which resources were unreachable.
167+
168+ ### Partial success granularity limitations
169+
170+ At a certain level of request scope granularity, an API is simply unable to
171+ enumerate the resources that are unreachable. For example, global-only APIs may
172+ be unable to provide granularity at a localized collection level. In such a
173+ case, preemptively returning an error when ` return_partial_success=true `
174+ protects the user from the risks of the alternative - expecting unreachable
175+ resources if there was an issue, but not getting any, thus falsely assuming
176+ everything was retrieved. This aligns with guidance herein that suggests failing
177+ requests that cannot be fulfilled preemptively.
178+
94179## Further reading
95180
96181- For listing across collections, see [ AIP-159] [ ] .
97182
183+ ## Changelog
184+
185+ - ** 2024-07-19** : Add guidance for brownfield adoption of partial success.
186+
98187[ aip-159 ] : ./0159.md
0 commit comments