From d22265b81c8a1ea60802e77f2e98d6b48430bceb Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Fri, 12 Apr 2024 12:15:15 -0500 Subject: [PATCH 01/11] Copy Google AIP 231 --- aep/general/0231/aep.md.j2 | 182 ++++++++++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 3 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 983884b9..9b93b724 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -1,5 +1,181 @@ # Batch methods: Get -**Note:** This AEP has not yet been adopted. See -[this GitHub issue](https://github.com/aep-dev/aep.dev/issues/42) for more -information. +Some APIs need to allow users to get a specific set of resources at a +consistent time point (e.g. using a read transaction). A batch get method +provides this functionality. + +## Guidance + +APIs **may** support Batch Get using the following pattern: + +```proto +rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { + option (google.api.http) = { + get: "/v1/{parent=publishers/*}/books:batchGet" + }; +} +``` + +- The RPC's name **must** begin with `BatchGet`. The remainder of the RPC name + **should** be the plural form of the resource being retrieved. +- The request and response messages **must** match the RPC name, with + `Request` and `Response` suffixes. +- The HTTP verb **must** be `GET`. +- The HTTP URI **must** end with `:batchGet`. +- The URI path **should** represent the collection for the resource, matching + the collection used for simple CRUD operations. If the operation spans + parents, a dash (`-`) **may** be accepted as a wildcard. +- There **must not** be a body key in the `google.api.http` annotation. +- The operation **must** be atomic: it **must** fail for all resources or + succeed for all resources (no partial success). For situations requiring + partial failures, `List` ([AIP-132][]) methods **should** be used. + - If the operation covers multiple locations and at least one location is + down, the operation **must** fail. + +### Request message + +The request for a batch get method **should** be specified with the following +pattern: + +```proto +message BatchGetBooksRequest { + // The parent resource shared by all books being retrieved. + // Format: publishers/{publisher} + // If this is set, the parent of all of the books specified in `names` + // must match this field. + string parent = 1 [ + (google.api.resource_reference) = { + child_type: "library.googleapis.com/Book" + }]; + + // The names of the books to retrieve. + // A maximum of 1000 books can be retrieved in a batch. + // Format: publishers/{publisher}/books/{book} + repeated string names = 2 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "library.googleapis.com/Book" + }]; +} +``` + +- A `parent` field **should** be included, unless the resource being retrieved + is a top-level resource, to facilitate inclusion in the URI as + well to permit a single permissions check. If a caller sets this field, and + the parent collection in the name of any resource being retrieved does not + match, the request **must** fail. + - This field **should** be required if only 1 parent per request is allowed. + - The field **should** identify the [resource type][aip-122-parent] that it + references. + - The comment for the field **should** document the resource pattern. +- The request message **must** include a repeated field which accepts the + resource names specifying the resources to retrieve. The field **should** be + named `names`. + - If no resource names are provided, the API **should** error with + `INVALID_ARGUMENT`. + - The field **should** be required. + - The field **should** identify the [resource type][aip-122-names] that it + references. + - The comment for the field **should** document the resource pattern. +- Other fields besides `name` **may** be "hoisted" from the [standard Get + request][request-message]. There is no way to allow for these fields to + accept different values for different resources; if this is needed, use the + [alternative request message form](#nested-request-objects). +- Batch get **should not** support pagination because transactionality across + API calls would be extremely difficult to implement or enforce, and the + request defines the exact scope of the response anyway. +- The request message **must not** contain any other required fields, and + **should not** contain other optional fields except those described in this + or another AIP. +- The comment above the `names` field **should** document the maximum number of + requests allowed. + +### Response message + +The response for a batch get method **should** be specified with the following +pattern: + +```proto +message BatchGetBooksResponse { + // Books requested. + repeated Book books = 1; +} +``` + +- The response message **must** include one repeated field corresponding to the + resources being retrieved. +- The order of books in the response **must** be the same as the names in the + request. + +[aip-122-names]: ./0122.md#fields-representing-resource-names +[aip-122-parent]: ./0122.md#fields-representing-a-resources-parent +[request-message]: ./0131.md#request-message + +### Nested request objects + +If the [standard Get request message][request-message] contains a field besides +the resource name that needs to be different between different resources being +requested, the batch message **may** alternatively hold a `repeated` field of +the [standard Get request message][request-message]. This is generally +discouraged unless your use case really requires it. + +The request for a batch get method using this approach **should** be specified +with the following pattern: + +```proto +message BatchGetBooksRequest { + // The parent resource shared by all books being retrieved. + // Format: publishers/{publisher} + // If this is set, the parent field in the GetBookRequest messages + // must either be empty or match this field. + string parent = 1 [ + (google.api.resource_reference) = { + child_type: "library.googleapis.com/Book" + }]; + + // The requests specifying the books to retrieve. + // A maximum of 1000 books can be retrieved in a batch. + repeated GetBookRequest requests = 2 + [(google.api.field_behavior) = REQUIRED]; +} +``` + +- A `parent` field **should** be included. If a caller sets this field, and the + parent collection in the name of any resource being retrieved does not match, + the request **must** fail. + - This field **should** be required if only 1 parent per request is allowed. + - The field **should** identify the [resource type][aip-122-parent] that it + references. + - The comment for the field **should** document the resource pattern. +- The request message **must** include a repeated field which accepts the + request messages specifying the resources to retrieve, as specified for + [standard Get methods][request-message]. The field **should** be named + `requests`. + - The field **should** be required. +- Other fields **may** be "hoisted" from the [standard Get + request][request-message], which means that the field can be set at either + the batch level or child request level. Similar to `parent`, if both the + batch level and child request level are set for the same field, the values + **must** match. +- Batch get **should not** support pagination because transactionality across + API calls would be extremely difficult to implement or enforce, and the + request defines the exact scope of the response anyway. +- The request message **must not** contain any other required fields, and + **should not** contain other optional fields except those described in this + or another AIP. +- The comment above the `requests` field **should** document the maximum number + of requests allowed. + +[aip-132]: https://aip.dev/132 + +## Changelog + +- **2022-06-02:** Changed suffix descriptions to eliminate superfluous "-". +- **2020-09-16**: Suggested annotating `parent`, `names`, and `requests` fields. +- **2020-08-27**: Removed parent recommendations for top-level resources. +- **2020-03-24**: Clarified behavior if no resource names are sent. +- **2019-09-11**: Changed the primary recommendation to specify a repeated + string instead of a repeated standard Get request message. Moved the original + recommendation into its own section. +- **2019-08-01**: Changed the examples from "shelves" to "publishers", to + present a better example of resource ownership. \ No newline at end of file From d391a22b97e3086ef7e1028d5104f63c7c24bd65 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Mon, 22 Apr 2024 08:15:09 -0500 Subject: [PATCH 02/11] Mechanical AIP to AEP updates --- aep/general/0231/aep.md.j2 | 54 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 9b93b724..e7817831 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -16,9 +16,9 @@ rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { } ``` -- The RPC's name **must** begin with `BatchGet`. The remainder of the RPC name +- The method's name **must** begin with `BatchGet`. The remainder of the method name **should** be the plural form of the resource being retrieved. -- The request and response messages **must** match the RPC name, with +- The request and responses **must** match the method name, with `Request` and `Response` suffixes. - The HTTP verb **must** be `GET`. - The HTTP URI **must** end with `:batchGet`. @@ -28,11 +28,11 @@ rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { - There **must not** be a body key in the `google.api.http` annotation. - The operation **must** be atomic: it **must** fail for all resources or succeed for all resources (no partial success). For situations requiring - partial failures, `List` ([AIP-132][]) methods **should** be used. + partial failures, `List` ([AEP-132]) methods **should** be used. - If the operation covers multiple locations and at least one location is down, the operation **must** fail. -### Request message +### Request The request for a batch get method **should** be specified with the following pattern: @@ -45,7 +45,7 @@ message BatchGetBooksRequest { // must match this field. string parent = 1 [ (google.api.resource_reference) = { - child_type: "library.googleapis.com/Book" + child_type: "library.com/Book" }]; // The names of the books to retrieve. @@ -54,7 +54,7 @@ message BatchGetBooksRequest { repeated string names = 2 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { - type: "library.googleapis.com/Book" + type: "library.com/Book" }]; } ``` @@ -65,32 +65,32 @@ message BatchGetBooksRequest { the parent collection in the name of any resource being retrieved does not match, the request **must** fail. - This field **should** be required if only 1 parent per request is allowed. - - The field **should** identify the [resource type][aip-122-parent] that it + - The field **should** identify the [resource type][aep-122-parent] that it references. - The comment for the field **should** document the resource pattern. -- The request message **must** include a repeated field which accepts the +- The request **must** include a repeated field which accepts the resource names specifying the resources to retrieve. The field **should** be named `names`. - If no resource names are provided, the API **should** error with `INVALID_ARGUMENT`. - The field **should** be required. - - The field **should** identify the [resource type][aip-122-names] that it + - The field **should** identify the [resource type][aep-122-names] that it references. - The comment for the field **should** document the resource pattern. - Other fields besides `name` **may** be "hoisted" from the [standard Get request][request-message]. There is no way to allow for these fields to accept different values for different resources; if this is needed, use the - [alternative request message form](#nested-request-objects). + [alternative request form](#nested-request-objects). - Batch get **should not** support pagination because transactionality across API calls would be extremely difficult to implement or enforce, and the request defines the exact scope of the response anyway. -- The request message **must not** contain any other required fields, and +- The request **must not** contain any other required fields, and **should not** contain other optional fields except those described in this - or another AIP. + or another AEP. - The comment above the `names` field **should** document the maximum number of requests allowed. -### Response message +### Response The response for a batch get method **should** be specified with the following pattern: @@ -102,21 +102,21 @@ message BatchGetBooksResponse { } ``` -- The response message **must** include one repeated field corresponding to the +- The response **must** include one repeated field corresponding to the resources being retrieved. - The order of books in the response **must** be the same as the names in the request. -[aip-122-names]: ./0122.md#fields-representing-resource-names -[aip-122-parent]: ./0122.md#fields-representing-a-resources-parent +[aep-122-names]: ./0122.md#fields-representing-resource-names +[aep-122-parent]: ./0122.md#fields-representing-a-resources-parent [request-message]: ./0131.md#request-message ### Nested request objects -If the [standard Get request message][request-message] contains a field besides +If the [standard Get request][request-message] contains a field besides the resource name that needs to be different between different resources being requested, the batch message **may** alternatively hold a `repeated` field of -the [standard Get request message][request-message]. This is generally +the [standard Get request][request-message]. This is generally discouraged unless your use case really requires it. The request for a batch get method using this approach **should** be specified @@ -126,11 +126,11 @@ with the following pattern: message BatchGetBooksRequest { // The parent resource shared by all books being retrieved. // Format: publishers/{publisher} - // If this is set, the parent field in the GetBookRequest messages + // If this is set, the parent field in the GetBookRequests // must either be empty or match this field. string parent = 1 [ (google.api.resource_reference) = { - child_type: "library.googleapis.com/Book" + child_type: "library.com/Book" }]; // The requests specifying the books to retrieve. @@ -144,11 +144,11 @@ message BatchGetBooksRequest { parent collection in the name of any resource being retrieved does not match, the request **must** fail. - This field **should** be required if only 1 parent per request is allowed. - - The field **should** identify the [resource type][aip-122-parent] that it + - The field **should** identify the [resource type][aep-122-parent] that it references. - The comment for the field **should** document the resource pattern. -- The request message **must** include a repeated field which accepts the - request messages specifying the resources to retrieve, as specified for +- The request **must** include a repeated field which accepts the + requests specifying the resources to retrieve, as specified for [standard Get methods][request-message]. The field **should** be named `requests`. - The field **should** be required. @@ -160,13 +160,13 @@ message BatchGetBooksRequest { - Batch get **should not** support pagination because transactionality across API calls would be extremely difficult to implement or enforce, and the request defines the exact scope of the response anyway. -- The request message **must not** contain any other required fields, and +- The request **must not** contain any other required fields, and **should not** contain other optional fields except those described in this - or another AIP. + or another AEP. - The comment above the `requests` field **should** document the maximum number of requests allowed. -[aip-132]: https://aip.dev/132 +[aep-132]: https://aep.dev/132 ## Changelog @@ -175,7 +175,7 @@ message BatchGetBooksRequest { - **2020-08-27**: Removed parent recommendations for top-level resources. - **2020-03-24**: Clarified behavior if no resource names are sent. - **2019-09-11**: Changed the primary recommendation to specify a repeated - string instead of a repeated standard Get request message. Moved the original + string instead of a repeated standard Get request. Moved the original recommendation into its own section. - **2019-08-01**: Changed the examples from "shelves" to "publishers", to present a better example of resource ownership. \ No newline at end of file From 15ac5e9e5b0ce895eb82000e8b15788ed91f3486 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Mon, 22 Apr 2024 09:21:02 -0500 Subject: [PATCH 03/11] Add OAS-specific guidance --- aep/general/0231/aep.md.j2 | 149 +++++++++++++---------------- aep/general/0231/aep.yaml | 4 +- aep/general/0231/batchget.oas.yaml | 58 +++++++++++ 3 files changed, 128 insertions(+), 83 deletions(-) create mode 100644 aep/general/0231/batchget.oas.yaml diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index e7817831..52af193b 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -8,6 +8,8 @@ provides this functionality. APIs **may** support Batch Get using the following pattern: +{% tab proto -%} + ```proto rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { option (google.api.http) = { @@ -16,10 +18,16 @@ rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { } ``` -- The method's name **must** begin with `BatchGet`. The remainder of the method name - **should** be the plural form of the resource being retrieved. -- The request and responses **must** match the method name, with - `Request` and `Response` suffixes. +{% tab oas %} + +{% sample 'batchget.oas.yaml', 'paths' %} + +{% endtabs %} + +- The method's name **must** begin with `BatchGet`. The remainder of the method + name **should** be the plural form of the resource being retrieved. +- The request and responses **must** match the method name, with `Request` and + `Response` suffixes. - The HTTP verb **must** be `GET`. - The HTTP URI **must** end with `:batchGet`. - The URI path **should** represent the collection for the resource, matching @@ -37,6 +45,8 @@ rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { The request for a batch get method **should** be specified with the following pattern: +{% tab proto -%} + ```proto message BatchGetBooksRequest { // The parent resource shared by all books being retrieved. @@ -60,17 +70,17 @@ message BatchGetBooksRequest { ``` - A `parent` field **should** be included, unless the resource being retrieved - is a top-level resource, to facilitate inclusion in the URI as - well to permit a single permissions check. If a caller sets this field, and - the parent collection in the name of any resource being retrieved does not - match, the request **must** fail. + is a top-level resource, to facilitate inclusion in the URI as well to permit + a single permissions check. If a caller sets this field, and the parent + collection in the name of any resource being retrieved does not match, the + request **must** fail. - This field **should** be required if only 1 parent per request is allowed. - The field **should** identify the [resource type][aep-122-parent] that it references. - The comment for the field **should** document the resource pattern. -- The request **must** include a repeated field which accepts the - resource names specifying the resources to retrieve. The field **should** be - named `names`. +- The request **must** include a repeated field which accepts the resource + names specifying the resources to retrieve. The field **should** be named + `names`. - If no resource names are provided, the API **should** error with `INVALID_ARGUMENT`. - The field **should** be required. @@ -84,17 +94,46 @@ message BatchGetBooksRequest { - Batch get **should not** support pagination because transactionality across API calls would be extremely difficult to implement or enforce, and the request defines the exact scope of the response anyway. -- The request **must not** contain any other required fields, and - **should not** contain other optional fields except those described in this - or another AEP. +- The request **must not** contain any other required fields, and **should + not** contain other optional fields except those described in this or another + AEP. - The comment above the `names` field **should** document the maximum number of requests allowed. +{% tab oas %} + +- The request **must** include a query parameter which accepts an array of + resource names specifying the resources to retrieve. The parameter **should** + be named `names`. + - If no resource names are provided, the API **should** error with status + code `400 Bad Request`. + - The parameter **should** be required. + - The parameter **should** identify the [resource type][aep-122-names] that + it references. + - The comment for the parameter **should** document the resource pattern. +- Other parameters besides `name` **may** be "hoisted" from the [standard Get + request][request-message]. There is no way to allow for these parameters to + accept different values for different resources; if this is needed, use the + [alternative request form](#nested-request-objects). +- The request **must not** contain any other required parameters, and **should + not** contain other optional parameters except those described in this or + another AEP. +- The `names` parameter **should** document the maximum number of values + allowed in the array. + +{% endtabs %} + +- Batch get **should not** support pagination because transactionality across + API calls would be extremely difficult to implement or enforce, and the + request defines the exact scope of the response anyway. + ### Response The response for a batch get method **should** be specified with the following pattern: +{% tab proto -%} + ```proto message BatchGetBooksResponse { // Books requested. @@ -102,80 +141,28 @@ message BatchGetBooksResponse { } ``` -- The response **must** include one repeated field corresponding to the +- The response message **must** include one repeated field corresponding to the resources being retrieved. -- The order of books in the response **must** be the same as the names in the - request. -[aep-122-names]: ./0122.md#fields-representing-resource-names -[aep-122-parent]: ./0122.md#fields-representing-a-resources-parent -[request-message]: ./0131.md#request-message +{% tab oas %} -### Nested request objects +- The response schema **must** be an array with each item containing one of the + requested resources. -If the [standard Get request][request-message] contains a field besides -the resource name that needs to be different between different resources being -requested, the batch message **may** alternatively hold a `repeated` field of -the [standard Get request][request-message]. This is generally -discouraged unless your use case really requires it. +{% endtabs %} -The request for a batch get method using this approach **should** be specified -with the following pattern: +- The order of resources in the response **must** be the same as the names in + the request. -```proto -message BatchGetBooksRequest { - // The parent resource shared by all books being retrieved. - // Format: publishers/{publisher} - // If this is set, the parent field in the GetBookRequests - // must either be empty or match this field. - string parent = 1 [ - (google.api.resource_reference) = { - child_type: "library.com/Book" - }]; +## Changelog - // The requests specifying the books to retrieve. - // A maximum of 1000 books can be retrieved in a batch. - repeated GetBookRequest requests = 2 - [(google.api.field_behavior) = REQUIRED]; -} -``` +- **2024-04-22:** Adopt from Google AIP https://google.aip.dev/231 with the + following changes: + - Dropped the "nested requests" pattern. -- A `parent` field **should** be included. If a caller sets this field, and the - parent collection in the name of any resource being retrieved does not match, - the request **must** fail. - - This field **should** be required if only 1 parent per request is allowed. - - The field **should** identify the [resource type][aep-122-parent] that it - references. - - The comment for the field **should** document the resource pattern. -- The request **must** include a repeated field which accepts the - requests specifying the resources to retrieve, as specified for - [standard Get methods][request-message]. The field **should** be named - `requests`. - - The field **should** be required. -- Other fields **may** be "hoisted" from the [standard Get - request][request-message], which means that the field can be set at either - the batch level or child request level. Similar to `parent`, if both the - batch level and child request level are set for the same field, the values - **must** match. -- Batch get **should not** support pagination because transactionality across - API calls would be extremely difficult to implement or enforce, and the - request defines the exact scope of the response anyway. -- The request **must not** contain any other required fields, and - **should not** contain other optional fields except those described in this - or another AEP. -- The comment above the `requests` field **should** document the maximum number - of requests allowed. + +[aep-122-names]: ./0122.md#fields-representing-resource-names +[aep-122-parent]: ./0122.md#fields-representing-a-resources-parent [aep-132]: https://aep.dev/132 - -## Changelog - -- **2022-06-02:** Changed suffix descriptions to eliminate superfluous "-". -- **2020-09-16**: Suggested annotating `parent`, `names`, and `requests` fields. -- **2020-08-27**: Removed parent recommendations for top-level resources. -- **2020-03-24**: Clarified behavior if no resource names are sent. -- **2019-09-11**: Changed the primary recommendation to specify a repeated - string instead of a repeated standard Get request. Moved the original - recommendation into its own section. -- **2019-08-01**: Changed the examples from "shelves" to "publishers", to - present a better example of resource ownership. \ No newline at end of file +[request-message]: ./0131.md#request-message diff --git a/aep/general/0231/aep.yaml b/aep/general/0231/aep.yaml index 997d2e00..96b556cd 100644 --- a/aep/general/0231/aep.yaml +++ b/aep/general/0231/aep.yaml @@ -1,7 +1,7 @@ --- id: 231 -state: reviewing +state: approved slug: batch-get -created: 2023-01-22 +created: 2024-04-22 placement: category: batch-methods diff --git a/aep/general/0231/batchget.oas.yaml b/aep/general/0231/batchget.oas.yaml new file mode 100644 index 00000000..ddbba3a8 --- /dev/null +++ b/aep/general/0231/batchget.oas.yaml @@ -0,0 +1,58 @@ +openapi: 3.0.3 +info: + title: Library + version: 1.0.0 +paths: + /publishers/{publisherId}/books:BatchGet: + parameters: + - name: publisherId + in: path + required: true + schema: + type: string + get: + operationId: BatchGetBooks + description: Get multiple books in a batch. + parameters: + - name: names + in: query + required: false + schema: + type: array + items: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Book' +components: + schemas: + Book: + description: A representation of a single book. + properties: + name: + type: string + description: | + The name of the book. + Format: publishers/{publisher}/books/{book} + isbn: + type: string + description: | + The ISBN (International Standard Book Number) for this book. + title: + type: string + description: The title of the book. + authors: + type: array + items: + type: string + description: The author or authors of the book. + rating: + type: number + format: float + description: The rating assigned to the book. From 33dbbabdc5f65e9fc4757fa6b1b57b0e37ed6a96 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Sat, 27 Apr 2024 08:25:28 -0500 Subject: [PATCH 04/11] Apply suggestions from PR review Co-authored-by: Richard Frankel --- aep/general/0231/aep.md.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 52af193b..9177d240 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -6,7 +6,7 @@ provides this functionality. ## Guidance -APIs **may** support Batch Get using the following pattern: +APIs **may** support batch get using the following pattern: {% tab proto -%} @@ -26,7 +26,7 @@ rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { - The method's name **must** begin with `BatchGet`. The remainder of the method name **should** be the plural form of the resource being retrieved. -- The request and responses **must** match the method name, with `Request` and +- The request and response schemas **must** match the method name, with `Request` and `Response` suffixes. - The HTTP verb **must** be `GET`. - The HTTP URI **must** end with `:batchGet`. @@ -36,7 +36,7 @@ rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { - There **must not** be a body key in the `google.api.http` annotation. - The operation **must** be atomic: it **must** fail for all resources or succeed for all resources (no partial success). For situations requiring - partial failures, `List` ([AEP-132]) methods **should** be used. + partial failures, `List` (AEP-132) methods **should** be used. - If the operation covers multiple locations and at least one location is down, the operation **must** fail. From 8a0b1630cea2d1c1744082f6f946ae3fe0c19ee5 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Sat, 27 Apr 2024 08:42:40 -0500 Subject: [PATCH 05/11] Change name to path --- aep/general/0231/aep.md.j2 | 44 ++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 9177d240..4f0b833e 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -51,17 +51,17 @@ pattern: message BatchGetBooksRequest { // The parent resource shared by all books being retrieved. // Format: publishers/{publisher} - // If this is set, the parent of all of the books specified in `names` + // If this is set, the parent of all of the books specified in `paths` // must match this field. string parent = 1 [ (google.api.resource_reference) = { child_type: "library.com/Book" }]; - // The names of the books to retrieve. + // The paths of the books to retrieve. // A maximum of 1000 books can be retrieved in a batch. // Format: publishers/{publisher}/books/{book} - repeated string names = 2 [ + repeated string paths = 2 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { type: "library.com/Book" @@ -72,22 +72,22 @@ message BatchGetBooksRequest { - A `parent` field **should** be included, unless the resource being retrieved is a top-level resource, to facilitate inclusion in the URI as well to permit a single permissions check. If a caller sets this field, and the parent - collection in the name of any resource being retrieved does not match, the + collection in the path of any resource being retrieved does not match, the request **must** fail. - This field **should** be required if only 1 parent per request is allowed. - The field **should** identify the [resource type][aep-122-parent] that it references. - The comment for the field **should** document the resource pattern. - The request **must** include a repeated field which accepts the resource - names specifying the resources to retrieve. The field **should** be named - `names`. - - If no resource names are provided, the API **should** error with + paths specifying the resources to retrieve. The field **should** be named + `paths`. + - If no resource paths are provided, the API **should** error with `INVALID_ARGUMENT`. - The field **should** be required. - - The field **should** identify the [resource type][aep-122-names] that it + - The field **should** identify the [resource type][aep-122-paths] that it references. - The comment for the field **should** document the resource pattern. -- Other fields besides `name` **may** be "hoisted" from the [standard Get +- Other fields besides `path` **may** be "hoisted" from the [standard Get request][request-message]. There is no way to allow for these fields to accept different values for different resources; if this is needed, use the [alternative request form](#nested-request-objects). @@ -97,28 +97,26 @@ message BatchGetBooksRequest { - The request **must not** contain any other required fields, and **should not** contain other optional fields except those described in this or another AEP. -- The comment above the `names` field **should** document the maximum number of - requests allowed. +- The comment above the `paths` field **should** document the maximum number of + paths allowed. {% tab oas %} - The request **must** include a query parameter which accepts an array of - resource names specifying the resources to retrieve. The parameter **should** - be named `names`. - - If no resource names are provided, the API **should** error with status + resource paths specifying the resources to retrieve. The parameter **should** + be named `paths`. + - If no resource paths are provided, the API **should** error with status code `400 Bad Request`. - The parameter **should** be required. - - The parameter **should** identify the [resource type][aep-122-names] that + - The parameter description **should** identify the [resource type][aep-122-paths] that it references. - - The comment for the parameter **should** document the resource pattern. -- Other parameters besides `name` **may** be "hoisted" from the [standard Get - request][request-message]. There is no way to allow for these parameters to - accept different values for different resources; if this is needed, use the - [alternative request form](#nested-request-objects). + - The parameter description **should** document the resource pattern. +- Other parameters besides `paths` **may** be "hoisted" from the [standard Get + request][request-message]. - The request **must not** contain any other required parameters, and **should not** contain other optional parameters except those described in this or another AEP. -- The `names` parameter **should** document the maximum number of values +- The `paths` parameter **should** document the maximum number of values allowed in the array. {% endtabs %} @@ -151,7 +149,7 @@ message BatchGetBooksResponse { {% endtabs %} -- The order of resources in the response **must** be the same as the names in +- The order of resources in the response **must** be the same as the paths in the request. ## Changelog @@ -162,7 +160,7 @@ message BatchGetBooksResponse { -[aep-122-names]: ./0122.md#fields-representing-resource-names +[aep-122-paths]: ./0122.md#fields-representing-resource-paths [aep-122-parent]: ./0122.md#fields-representing-a-resources-parent [aep-132]: https://aep.dev/132 [request-message]: ./0131.md#request-message From b88e06699395dbb59e395ba3bf2bd14193e54775 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Sat, 27 Apr 2024 09:32:34 -0500 Subject: [PATCH 06/11] Updates to address PR comments --- aep/general/0231/aep.md.j2 | 73 ++++++++++++------------------ aep/general/0231/batchget.oas.yaml | 9 +++- 2 files changed, 37 insertions(+), 45 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 4f0b833e..733d435b 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -6,34 +6,17 @@ provides this functionality. ## Guidance -APIs **may** support batch get using the following pattern: - -{% tab proto -%} - -```proto -rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { - option (google.api.http) = { - get: "/v1/{parent=publishers/*}/books:batchGet" - }; -} -``` - -{% tab oas %} - -{% sample 'batchget.oas.yaml', 'paths' %} - -{% endtabs %} +APIs **may** support batch get to retrieve a consistent set of resources. - The method's name **must** begin with `BatchGet`. The remainder of the method name **should** be the plural form of the resource being retrieved. -- The request and response schemas **must** match the method name, with `Request` and - `Response` suffixes. - The HTTP verb **must** be `GET`. - The HTTP URI **must** end with `:batchGet`. - The URI path **should** represent the collection for the resource, matching the collection used for simple CRUD operations. If the operation spans parents, a dash (`-`) **may** be accepted as a wildcard. -- There **must not** be a body key in the `google.api.http` annotation. +- There **must not** be a request body. + - If a GET request contains a body, the body **must** be ignored, and **must not** cause an error. - The operation **must** be atomic: it **must** fail for all resources or succeed for all resources (no partial success). For situations requiring partial failures, `List` (AEP-132) methods **should** be used. @@ -48,6 +31,12 @@ pattern: {% tab proto -%} ```proto +rpc BatchGetBooks(BatchGetBooksRequest) returns (BatchGetBooksResponse) { + option (google.api.http) = { + get: "/v1/{parent=publishers/*}/books:batchGet" + }; +} + message BatchGetBooksRequest { // The parent resource shared by all books being retrieved. // Format: publishers/{publisher} @@ -69,6 +58,8 @@ message BatchGetBooksRequest { } ``` +- The request and response schemas **must** match the method name, with `Request` and + `Response` suffixes. - A `parent` field **should** be included, unless the resource being retrieved is a top-level resource, to facilitate inclusion in the URI as well to permit a single permissions check. If a caller sets this field, and the parent @@ -87,43 +78,39 @@ message BatchGetBooksRequest { - The field **should** identify the [resource type][aep-122-paths] that it references. - The comment for the field **should** document the resource pattern. -- Other fields besides `path` **may** be "hoisted" from the [standard Get - request][request-message]. There is no way to allow for these fields to - accept different values for different resources; if this is needed, use the - [alternative request form](#nested-request-objects). -- Batch get **should not** support pagination because transactionality across - API calls would be extremely difficult to implement or enforce, and the - request defines the exact scope of the response anyway. -- The request **must not** contain any other required fields, and **should - not** contain other optional fields except those described in this or another - AEP. -- The comment above the `paths` field **should** document the maximum number of - paths allowed. + - The comment for the field **should** document the maximum number of + paths allowed. +- There **must not** be a body key in the `google.api.http` annotation. {% tab oas %} +{% sample 'batchget.oas.yaml', 'paths' %} + - The request **must** include a query parameter which accepts an array of resource paths specifying the resources to retrieve. The parameter **should** be named `paths`. - If no resource paths are provided, the API **should** error with status code `400 Bad Request`. + - If the collection in the path of any resource does not match the collection + of the request URL, the request **must** fail. - The parameter **should** be required. - - The parameter description **should** identify the [resource type][aep-122-paths] that - it references. - - The parameter description **should** document the resource pattern. -- Other parameters besides `paths` **may** be "hoisted" from the [standard Get - request][request-message]. -- The request **must not** contain any other required parameters, and **should - not** contain other optional parameters except those described in this or - another AEP. -- The `paths` parameter **should** document the maximum number of values - allowed in the array. + - The parameter description **should** identify the [resource type][aep-122-paths] + that it references. + - The parameter `description` **should** document the pattern for path values. + - The parameter `schema` **should** include a `maxItems` attribute to specify + the maximum number of paths allowed. +- The method definition **must not** have a `requestBody` defined. {% endtabs %} +- Other parameters besides `paths` **may** be "hoisted" from the [standard Get + request][get-request]. - Batch get **should not** support pagination because transactionality across API calls would be extremely difficult to implement or enforce, and the request defines the exact scope of the response anyway. +- The request **must not** contain any other required parameters, and **should + not** contain other optional parameters except those described in this or + another AEP. ### Response @@ -163,4 +150,4 @@ message BatchGetBooksResponse { [aep-122-paths]: ./0122.md#fields-representing-resource-paths [aep-122-parent]: ./0122.md#fields-representing-a-resources-parent [aep-132]: https://aep.dev/132 -[request-message]: ./0131.md#request-message +[get-request]: ./0131.md#get-request diff --git a/aep/general/0231/batchget.oas.yaml b/aep/general/0231/batchget.oas.yaml index ddbba3a8..951579e8 100644 --- a/aep/general/0231/batchget.oas.yaml +++ b/aep/general/0231/batchget.oas.yaml @@ -14,11 +14,16 @@ paths: operationId: BatchGetBooks description: Get multiple books in a batch. parameters: - - name: names + - name: paths in: query - required: false + required: true + description: >- + The paths of the books to retrieve. Format: + publishers/{publisherId}/books/{book} schema: type: array + minItems: 1 + maxItems: 1000 items: type: string responses: From 9922cee2a8a15a27a72854a2d0c737df27b6d421 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Fri, 17 May 2024 08:28:39 -0600 Subject: [PATCH 07/11] Apply suggestions from PR review Co-authored-by: Richard Frankel --- aep/general/0231/aep.md.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 733d435b..39c90900 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -14,12 +14,12 @@ APIs **may** support batch get to retrieve a consistent set of resources. - The HTTP URI **must** end with `:batchGet`. - The URI path **should** represent the collection for the resource, matching the collection used for simple CRUD operations. If the operation spans - parents, a dash (`-`) **may** be accepted as a wildcard. + parents, a [wilcard](./reading-across-collections) **may** be accepted. - There **must not** be a request body. - If a GET request contains a body, the body **must** be ignored, and **must not** cause an error. - The operation **must** be atomic: it **must** fail for all resources or succeed for all resources (no partial success). For situations requiring - partial failures, `List` (AEP-132) methods **should** be used. + partial failures, [`List`](./list) methods **should** be used. - If the operation covers multiple locations and at least one location is down, the operation **must** fail. @@ -75,7 +75,7 @@ message BatchGetBooksRequest { - If no resource paths are provided, the API **should** error with `INVALID_ARGUMENT`. - The field **should** be required. - - The field **should** identify the [resource type][aep-122-paths] that it + - The field **should** identify the [resource type](./paths) that it references. - The comment for the field **should** document the resource pattern. - The comment for the field **should** document the maximum number of From cc4f44d62cf4990bc30286e727b091ab97aba382 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Fri, 17 May 2024 08:39:39 -0600 Subject: [PATCH 08/11] Change response schema to be consistent with List method --- aep/general/0231/aep.md.j2 | 49 ++++++++++++++++++++++++------ aep/general/0231/batchget.oas.yaml | 9 ++++-- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 39c90900..e18bb778 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -16,7 +16,8 @@ APIs **may** support batch get to retrieve a consistent set of resources. the collection used for simple CRUD operations. If the operation spans parents, a [wilcard](./reading-across-collections) **may** be accepted. - There **must not** be a request body. - - If a GET request contains a body, the body **must** be ignored, and **must not** cause an error. + - If a GET request contains a body, the body **must** be ignored, and **must + not** cause an error. - The operation **must** be atomic: it **must** fail for all resources or succeed for all resources (no partial success). For situations requiring partial failures, [`List`](./list) methods **should** be used. @@ -58,8 +59,8 @@ message BatchGetBooksRequest { } ``` -- The request and response schemas **must** match the method name, with `Request` and - `Response` suffixes. +- The request and response schemas **must** match the method name, with + `Request` and `Response` suffixes. - A `parent` field **should** be included, unless the resource being retrieved is a top-level resource, to facilitate inclusion in the URI as well to permit a single permissions check. If a caller sets this field, and the parent @@ -78,8 +79,8 @@ message BatchGetBooksRequest { - The field **should** identify the [resource type](./paths) that it references. - The comment for the field **should** document the resource pattern. - - The comment for the field **should** document the maximum number of - paths allowed. + - The comment for the field **should** document the maximum number of paths + allowed. - There **must not** be a body key in the `google.api.http` annotation. {% tab oas %} @@ -94,9 +95,10 @@ message BatchGetBooksRequest { - If the collection in the path of any resource does not match the collection of the request URL, the request **must** fail. - The parameter **should** be required. - - The parameter description **should** identify the [resource type][aep-122-paths] - that it references. - - The parameter `description` **should** document the pattern for path values. + - The parameter description **should** identify the [resource + type][aep-122-paths] that it references. + - The parameter `description` **should** document the pattern for path + values. - The parameter `schema` **should** include a `maxItems` attribute to specify the maximum number of paths allowed. - The method definition **must not** have a `requestBody` defined. @@ -131,8 +133,34 @@ message BatchGetBooksResponse { {% tab oas %} -- The response schema **must** be an array with each item containing one of the - requested resources. +- The response schema **must** be `type: object` with a single array property + with each item containing one of the requested resources. + +```json +{ + "results": [ + { + "name": "publishers/lacroix/books/les-mis", + "isbn": "978-037-540317-0", + "title": "Les Misérables", + "authors": ["Victor Hugo"], + "rating": 9.6 + }, + { + "name": "publishers/lacroix/books/hunchback-of-notre-dame", + "isbn": "978-140-274575-1", + "title": "The Hunchback of Notre Dame", + "authors": ["Victor Hugo"], + "rating": 9.3 + } + ] +} +``` + +- The array of resources **must** be named `results` and contain resources with + no additional wrapping. +- There must not be a `nextPageToken` field as batch get operations are not + pageable. {% endtabs %} @@ -144,6 +172,7 @@ message BatchGetBooksResponse { - **2024-04-22:** Adopt from Google AIP https://google.aip.dev/231 with the following changes: - Dropped the "nested requests" pattern. + - Changed the response schema to an object with `results` array property. diff --git a/aep/general/0231/batchget.oas.yaml b/aep/general/0231/batchget.oas.yaml index 951579e8..395e1d5d 100644 --- a/aep/general/0231/batchget.oas.yaml +++ b/aep/general/0231/batchget.oas.yaml @@ -32,9 +32,12 @@ paths: content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/Book' + type: object + properties: + results: + type: array + items: + $ref: '#/components/schemas/Book' components: schemas: Book: From 4d4be17e99771811b1c328697851ebc2fd033f6c Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Fri, 7 Jun 2024 11:21:30 -0700 Subject: [PATCH 09/11] Changed shoulds to musts as discussed in weekly meeting --- aep/general/0231/aep.md.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index e18bb778..eb4d1253 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -9,10 +9,10 @@ provides this functionality. APIs **may** support batch get to retrieve a consistent set of resources. - The method's name **must** begin with `BatchGet`. The remainder of the method - name **should** be the plural form of the resource being retrieved. + name **must** be the plural form of the resource being retrieved. - The HTTP verb **must** be `GET`. - The HTTP URI **must** end with `:batchGet`. -- The URI path **should** represent the collection for the resource, matching +- The URI path **must** represent the collection for the resource, matching the collection used for simple CRUD operations. If the operation spans parents, a [wilcard](./reading-across-collections) **may** be accepted. - There **must not** be a request body. From f1c1bbab356adcba6df032a9bd084648a1d15a21 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Fri, 23 Aug 2024 17:21:24 -0500 Subject: [PATCH 10/11] Resolve outstanding issues for Batch Get --- aep/general/0231/aep.md.j2 | 84 +++++++++++++++--------------- aep/general/0231/batchget.oas.yaml | 7 ++- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index eb4d1253..05c5e651 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -11,24 +11,38 @@ APIs **may** support batch get to retrieve a consistent set of resources. - The method's name **must** begin with `BatchGet`. The remainder of the method name **must** be the plural form of the resource being retrieved. - The HTTP verb **must** be `GET`. -- The HTTP URI **must** end with `:batchGet`. -- The URI path **must** represent the collection for the resource, matching - the collection used for simple CRUD operations. If the operation spans - parents, a [wilcard](./reading-across-collections) **may** be accepted. +- The HTTP URI **must** end with `:BatchGet`. +- The URI path **must** represent the collection for the resource, matching the + collection used for simple CRUD operations. If the operation spans parents, a + [wilcard](./reading-across-collections) **may** be accepted. - There **must not** be a request body. - If a GET request contains a body, the body **must** be ignored, and **must not** cause an error. -- The operation **must** be atomic: it **must** fail for all resources or - succeed for all resources (no partial success). For situations requiring - partial failures, [`List`](./list) methods **should** be used. - - If the operation covers multiple locations and at least one location is - down, the operation **must** fail. ### Request The request for a batch get method **should** be specified with the following pattern: +- The request **must** include an array parameter which accepts the resource + paths specifying the resources to retrieve. The parameter **should** be named + `paths`. + - If no resource paths are provided, the API **should** error with + `INVALID_ARGUMENT`. + - The parameter **should** be required. + - The parameter **should** identify the [resource type](./paths) that it + references. + - The parameter should define the pattern of the resource path values. + - The parameter should define the maximum number of paths allowed. +- Other parameters besides `paths` **may** be "hoisted" from the [standard Get + request][get-request]. +- Batch get **should not** support pagination because transactionality across + API calls would be extremely difficult to implement or enforce, and the + request defines the exact scope of the response anyway. +- The request **must not** contain any other required parameters, and **should + not** contain other optional parameters except those described in this or + another AEP. + {% tab proto -%} ```proto @@ -70,50 +84,23 @@ message BatchGetBooksRequest { - The field **should** identify the [resource type][aep-122-parent] that it references. - The comment for the field **should** document the resource pattern. -- The request **must** include a repeated field which accepts the resource - paths specifying the resources to retrieve. The field **should** be named - `paths`. - - If no resource paths are provided, the API **should** error with - `INVALID_ARGUMENT`. - - The field **should** be required. - - The field **should** identify the [resource type](./paths) that it - references. - - The comment for the field **should** document the resource pattern. - - The comment for the field **should** document the maximum number of paths - allowed. - There **must not** be a body key in the `google.api.http` annotation. {% tab oas %} {% sample 'batchget.oas.yaml', 'paths' %} -- The request **must** include a query parameter which accepts an array of +- The `paths` parameter **must** be a query parameter which accepts an array of resource paths specifying the resources to retrieve. The parameter **should** be named `paths`. - If no resource paths are provided, the API **should** error with status code `400 Bad Request`. - If the collection in the path of any resource does not match the collection of the request URL, the request **must** fail. - - The parameter **should** be required. - - The parameter description **should** identify the [resource - type][aep-122-paths] that it references. - - The parameter `description` **should** document the pattern for path - values. - - The parameter `schema` **should** include a `maxItems` attribute to specify - the maximum number of paths allowed. - The method definition **must not** have a `requestBody` defined. {% endtabs %} -- Other parameters besides `paths` **may** be "hoisted" from the [standard Get - request][get-request]. -- Batch get **should not** support pagination because transactionality across - API calls would be extremely difficult to implement or enforce, and the - request defines the exact scope of the response anyway. -- The request **must not** contain any other required parameters, and **should - not** contain other optional parameters except those described in this or - another AEP. - ### Response The response for a batch get method **should** be specified with the following @@ -128,8 +115,10 @@ message BatchGetBooksResponse { } ``` -- The response message **must** include one repeated field corresponding to the - resources being retrieved. +- The response message **must** include one repeated field where its items may + either be a retrieved resource or an error structure describing an error that + occurred attempting to retrieve the resource. The error alternative would + only be present for non-transactional batch gets. {% tab oas %} @@ -146,6 +135,10 @@ message BatchGetBooksResponse { "authors": ["Victor Hugo"], "rating": 9.6 }, + { + "code": "NotFound", + "message": "The resource is not available" + } { "name": "publishers/lacroix/books/hunchback-of-notre-dame", "isbn": "978-140-274575-1", @@ -164,8 +157,15 @@ message BatchGetBooksResponse { {% endtabs %} -- The order of resources in the response **must** be the same as the paths in - the request. +- The order of resources/error objects in the response **must** be the same as + the paths in the request. + +### Support for transactional get + +The batch get method may support a transactional form of operation where the +get either succeeds for all requested resources or fails. When supported, the +method should define a boolean parameter `asTransaction` that the user must +specify with the value `true` to request transactional operation. ## Changelog @@ -173,6 +173,8 @@ message BatchGetBooksResponse { following changes: - Dropped the "nested requests" pattern. - Changed the response schema to an object with `results` array property. + - Made transactional operation optional and controlled by asTransaction + parameter. diff --git a/aep/general/0231/batchget.oas.yaml b/aep/general/0231/batchget.oas.yaml index 395e1d5d..085040fd 100644 --- a/aep/general/0231/batchget.oas.yaml +++ b/aep/general/0231/batchget.oas.yaml @@ -37,11 +37,14 @@ paths: results: type: array items: - $ref: '#/components/schemas/Book' + oneOf: + - $ref: '#/components/schemas/Book' + - $ref: '#/components/schemas/Error' components: schemas: Book: description: A representation of a single book. + type: object properties: name: type: string @@ -64,3 +67,5 @@ components: type: number format: float description: The rating assigned to the book. + Error: + type: object From 92af486e6b27059d76061f349e0ebf648fb8d64c Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Fri, 27 Sep 2024 14:26:42 -0500 Subject: [PATCH 11/11] Address PR review comments --- aep/general/0231/aep.md.j2 | 52 ++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/aep/general/0231/aep.md.j2 b/aep/general/0231/aep.md.j2 index 05c5e651..6ebfaea0 100644 --- a/aep/general/0231/aep.md.j2 +++ b/aep/general/0231/aep.md.j2 @@ -11,7 +11,7 @@ APIs **may** support batch get to retrieve a consistent set of resources. - The method's name **must** begin with `BatchGet`. The remainder of the method name **must** be the plural form of the resource being retrieved. - The HTTP verb **must** be `GET`. -- The HTTP URI **must** end with `:BatchGet`. +- The HTTP URI **must** end with `:batchGet`. - The URI path **must** represent the collection for the resource, matching the collection used for simple CRUD operations. If the operation spans parents, a [wilcard](./reading-across-collections) **may** be accepted. @@ -24,19 +24,18 @@ APIs **may** support batch get to retrieve a consistent set of resources. The request for a batch get method **should** be specified with the following pattern: -- The request **must** include an array parameter which accepts the resource - paths specifying the resources to retrieve. The parameter **should** be named - `paths`. +- The request **must** include an array field which accepts the resource paths + specifying the resources to retrieve. The field **should** be named `paths`. - If no resource paths are provided, the API **should** error with `INVALID_ARGUMENT`. - - The parameter **should** be required. + - The parameter **must** be required. - The parameter **should** identify the [resource type](./paths) that it references. - The parameter should define the pattern of the resource path values. - The parameter should define the maximum number of paths allowed. - Other parameters besides `paths` **may** be "hoisted" from the [standard Get request][get-request]. -- Batch get **should not** support pagination because transactionality across +- Batch Get **should not** support pagination because transactionality across API calls would be extremely difficult to implement or enforce, and the request defines the exact scope of the response anyway. - The request **must not** contain any other required parameters, and **should @@ -73,8 +72,7 @@ message BatchGetBooksRequest { } ``` -- The request and response schemas **must** match the method name, with - `Request` and `Response` suffixes. +- The request schema **must** match the method name, with `Request` suffix. - A `parent` field **should** be included, unless the resource being retrieved is a top-level resource, to facilitate inclusion in the URI as well to permit a single permissions check. If a caller sets this field, and the parent @@ -106,6 +104,18 @@ message BatchGetBooksRequest { The response for a batch get method **should** be specified with the following pattern: +- The response schema **must** match the method name, with `Response` suffix. +- The response schema **must** have a single array property where each item is + either a retrieved resource or an error structure describing an error that + occurred attempting to retrieve the resource. The error alternative would + only be present for non-transactional batch gets. +- The order of resources/error objects in the response **must** be the same as + the paths in the request. +- The array of resources **must** be named `results` and contain resources with + no additional wrapping. +- There must not be a `nextPageToken` field as batch get operations are not + pageable. + {% tab proto -%} ```proto @@ -115,15 +125,11 @@ message BatchGetBooksResponse { } ``` -- The response message **must** include one repeated field where its items may - either be a retrieved resource or an error structure describing an error that - occurred attempting to retrieve the resource. The error alternative would - only be present for non-transactional batch gets. - {% tab oas %} -- The response schema **must** be `type: object` with a single array property - with each item containing one of the requested resources. +{% sample 'batchget.oas.yaml', 'paths./publishers/{publisherId}/books:BatchGet.get.responses.200.content.application/json' %} + +Example response body: ```json { @@ -136,8 +142,8 @@ message BatchGetBooksResponse { "rating": 9.6 }, { - "code": "NotFound", - "message": "The resource is not available" + "type": "https://datatracker.ietf.org/doc/html/rfc9110#name-404-not-found", + "title": "The resource is not available" } { "name": "publishers/lacroix/books/hunchback-of-notre-dame", @@ -150,22 +156,14 @@ message BatchGetBooksResponse { } ``` -- The array of resources **must** be named `results` and contain resources with - no additional wrapping. -- There must not be a `nextPageToken` field as batch get operations are not - pageable. - {% endtabs %} -- The order of resources/error objects in the response **must** be the same as - the paths in the request. - ### Support for transactional get The batch get method may support a transactional form of operation where the get either succeeds for all requested resources or fails. When supported, the -method should define a boolean parameter `asTransaction` that the user must -specify with the value `true` to request transactional operation. +method should define a boolean parameter `transactional` that the user must +specify with the value `true` to request a transactional operation. ## Changelog