From a906082368d729cb54c86f6799f6cd2f776c478b Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Mon, 14 Jun 2021 14:03:03 -0700 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20AIP-159=20=E2=80=93=20Reading=20acr?= =?UTF-8?q?oss=20collections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aip/general/0159/aip.md | 63 +++++++++++++++++++++++++++++++++++++++ aip/general/0159/aip.yaml | 7 +++++ 2 files changed, 70 insertions(+) create mode 100644 aip/general/0159/aip.md create mode 100644 aip/general/0159/aip.yaml diff --git a/aip/general/0159/aip.md b/aip/general/0159/aip.md new file mode 100644 index 00000000..1dd23007 --- /dev/null +++ b/aip/general/0159/aip.md @@ -0,0 +1,63 @@ +# Reading across collections + +Sometimes, it is useful for a user to be able to retrieve resources across +multiple collections, or retrieve a single resource without needing to know +what collection it is in. + +## Guidance + +APIs **may** support reading resources across multiple collections by allowing +users to specify a `-` (the hyphen or dash character) as a wildcard character +in a standard [`List`][aip-132] operation: + +``` +GET /v1/publishers/-/books?filter=... +``` + +- The URI pattern **must** still be specified with `*` and permit the + collection to be specified; a URI pattern **must not** hard-code the `-` + character. +- The operation **must** explicitly document that this behavior is supported. +- The resources provided in the response **must** use the canonical name of the + resource, with the actual parent collection identifiers (instead of `-`). +- Services **may** support reading across collections on `List` requests + regardless of whether the identifiers of the child resources are guaranteed + to be unique. + - However, services **must not** support reading across collections on `Get` + requests if the child resources might have a collision. +- Cross-parent requests **should not** support `order_by`. If they do, the + field **must** document that it is best effort. This is because cross-parent + requests introduce ambiguity around ordering, especially if there is + difficulty reaching a parent (see AIP-217). + +**Important:** If listing across multiple collections introduces the +possibility of partial failures due to unreachable parents (such as when +listing across locations), the operation **must** indicate this following the +guidance in AIP-217. + +### Unique resource lookup + +Sometimes, a resource within a sub-collection has an identifier that is unique +across parent collections. In this case, it may be useful to allow a +[`Get`][aip-131] operation to retrieve that resource without knowing which +parent collection contains it. In such cases, APIs **may** allow users to +specify the wildcard collection ID `-` (the hyphen or dash character) to +represent any parent collection: + +``` +GET https://example.googleapis.com/v1/publishers/-/books/{book} +``` + +- The URI pattern **must** still be specified with `*` and permit the + collection to be specified; a URI pattern **must not** hard-code the `-` + character. +- The operation **must** explicitly document that this behavior is supported. +- The resource name in the response **must** use the canonical name of the + resource, with actual parent collection identifiers (instead of `-`). For + example, the request above returns a resource with a name like + `publishers/123/books/456`, _not_ `publishers/-/books/456`. +- The resource ID **must** be unique within parent collections. + +## Further reading + +- For partial failures due to unreachable resources, see AIP-217. diff --git a/aip/general/0159/aip.yaml b/aip/general/0159/aip.yaml new file mode 100644 index 00000000..3fbe1787 --- /dev/null +++ b/aip/general/0159/aip.yaml @@ -0,0 +1,7 @@ +--- +id: 159 +state: approved +created: 2019-07-26 +placement: + category: design-patterns + order: 70 From 8b586930cdbaffa750384c5c9d09994615d7bb65 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 31 Aug 2021 09:27:10 -0700 Subject: [PATCH 2/4] Incorporate most group feedback. --- aip/general/0159/aip.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/aip/general/0159/aip.md b/aip/general/0159/aip.md index 1dd23007..1bf8215d 100644 --- a/aip/general/0159/aip.md +++ b/aip/general/0159/aip.md @@ -14,18 +14,25 @@ in a standard [`List`][aip-132] operation: GET /v1/publishers/-/books?filter=... ``` -- The URI pattern **must** still be specified with `*` and permit the - collection to be specified; a URI pattern **must not** hard-code the `-` - character. +- The URI pattern **must** still accept a parameter to permit the collection to + be specified; a URI pattern **must not** hard-code the `-` character. - The operation **must** explicitly document that this behavior is supported. -- The resources provided in the response **must** use the canonical name of the - resource, with the actual parent collection identifiers (instead of `-`). +- Responses **must** populate the canonical parent ID rather than `-` if the + parent ID is normally provided in the resource in some way. + - If resources include the parent ID within the name of the resource, the + resources provided in the response **must** use the canonical name of the + resource, with the actual parent collection identifiers (instead of `-`). + - If resources include a field indicating the ID of the parent, resources + provided in the response **must** populate the canonical parent ID (instead + of `-`). - Services **may** support reading across collections on `List` requests regardless of whether the identifiers of the child resources are guaranteed to be unique. - However, services **must not** support reading across collections on `Get` requests if the child resources might have a collision. -- Cross-parent requests **should not** support `order_by`. If they do, the +- Cross-parent requests **may** support `order_by`. However, if reading across + collections requires consulting multiple backends, databases, or locations, + cross-parent requests **should not** support `order_by`, and if they do, the field **must** document that it is best effort. This is because cross-parent requests introduce ambiguity around ordering, especially if there is difficulty reaching a parent (see AIP-217). From 19fb8767baf07f40baefc37fc222bc5de706e8d6 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 7 Sep 2021 09:37:40 -0700 Subject: [PATCH 3/4] Incorporate consensus feedback. --- aip/general/0159/aip.md | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/aip/general/0159/aip.md b/aip/general/0159/aip.md index 1bf8215d..2125390c 100644 --- a/aip/general/0159/aip.md +++ b/aip/general/0159/aip.md @@ -6,9 +6,39 @@ what collection it is in. ## Guidance -APIs **may** support reading resources across multiple collections by allowing -users to specify a `-` (the hyphen or dash character) as a wildcard character -in a standard [`List`][aip-132] operation: +There are two potential approaches for reading resources across multiple +collections. Groups of related services **should**, as a unit, select a +preferred approach and apply it consistently. + +### Promoting Resources + +One approach is to evade the problem entirely by promoting resources above +their erstwhile parents in the event that reading across collections is likely +to be a requirement. + +In this approach, the parent becomes a field on the resource: + +```typescript +interface Book { + // The ID of the book's publisher + publisherId: string; + + // Other fields... +} +``` + +Similarly, the parent is removed from the URI: + +``` +GET /v1/books?filter... +``` + +### Wildcards + +The other approach is to use a wildcard character. Services **may** support +reading resources across multiple collections by allowing users to specify a +`-` (the hyphen or dash character) as a wildcard character in a standard +[`List`][aip-132] operation: ``` GET /v1/publishers/-/books?filter=... From 4f054c092972022b78e25f34299ba02021947a10 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 26 Oct 2021 09:23:57 -0700 Subject: [PATCH 4/4] Incorporate group feedback. --- aip/general/0159/aip.md | 52 ++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/aip/general/0159/aip.md b/aip/general/0159/aip.md index 2125390c..86e2c4a6 100644 --- a/aip/general/0159/aip.md +++ b/aip/general/0159/aip.md @@ -10,35 +10,11 @@ There are two potential approaches for reading resources across multiple collections. Groups of related services **should**, as a unit, select a preferred approach and apply it consistently. -### Promoting Resources - -One approach is to evade the problem entirely by promoting resources above -their erstwhile parents in the event that reading across collections is likely -to be a requirement. - -In this approach, the parent becomes a field on the resource: - -```typescript -interface Book { - // The ID of the book's publisher - publisherId: string; - - // Other fields... -} -``` - -Similarly, the parent is removed from the URI: - -``` -GET /v1/books?filter... -``` - ### Wildcards -The other approach is to use a wildcard character. Services **may** support -reading resources across multiple collections by allowing users to specify a -`-` (the hyphen or dash character) as a wildcard character in a standard -[`List`][aip-132] operation: +Services **may** support reading resources across multiple collections by +allowing users to specify a `-` (the hyphen or dash character) as a wildcard +character in a standard [`List`][aip-132] operation: ``` GET /v1/publishers/-/books?filter=... @@ -95,6 +71,28 @@ GET https://example.googleapis.com/v1/publishers/-/books/{book} `publishers/123/books/456`, _not_ `publishers/-/books/456`. - The resource ID **must** be unique within parent collections. +### Virtual Collections + +Services **may** create a _virtual collection_ (usually as an alternative to +the use of the wildcard character), which exists alongside the erstwhile parent +and provides child resources regardless of the parent they are under. + +The parent **must** be removed from the URI: + +``` +GET /v1/books?filter... +``` + +The service **must** still recognize the full path to the resource (e.g. +`/publishers/123/books/les-mis`) as the canonical path. Services **should** +send `308 Permanent Redirect` to the canonical path if a user attempts to +access a resource directly within the virtual collection (for example, +`/v1/books/les-mis`). + +**Note:** The child IDs **must** be unique across all parents for +`308 Permanent Redirect` to be appropriate; if they are not, the service +**must** send `404 Not Found` in this situation instead. + ## Further reading - For partial failures due to unreachable resources, see AIP-217.