Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt AEP 231 - Batch Get #177

Merged
merged 15 commits into from
Oct 25, 2024
169 changes: 166 additions & 3 deletions aep/general/0231/aep.md.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,168 @@
# 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
mkistler marked this conversation as resolved.
Show resolved Hide resolved
provides this functionality.

## Guidance

APIs **may** support Batch Get using the following pattern:
mkistler marked this conversation as resolved.
Show resolved Hide resolved

{% 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 %}

- The method's name **must** begin with `BatchGet`. The remainder of the method
name **should** be the plural form of the resource being retrieved.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- The request and responses **must** match the method name, with `Request` and
mkistler marked this conversation as resolved.
Show resolved Hide resolved
`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
mkistler marked this conversation as resolved.
Show resolved Hide resolved
the collection used for simple CRUD operations. If the operation spans
parents, a dash (`-`) **may** be accepted as a wildcard.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- There **must not** be a body key in the `google.api.http` annotation.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- 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.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- 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:

{% tab proto -%}

```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.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.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][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`.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- If no resource names are provided, the API **should** error with
mkistler marked this conversation as resolved.
Show resolved Hide resolved
`INVALID_ARGUMENT`.
- The field **should** be required.
- 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
mkistler marked this conversation as resolved.
Show resolved Hide resolved
request][request-message]. There is no way to allow for these fields to
mkistler marked this conversation as resolved.
Show resolved Hide resolved
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 `names` field **should** document the maximum number of
mkistler marked this conversation as resolved.
Show resolved Hide resolved
requests allowed.

{% tab oas %}
mkistler marked this conversation as resolved.
Show resolved Hide resolved

- 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`.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- 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
mkistler marked this conversation as resolved.
Show resolved Hide resolved
pattern:

{% tab proto -%}

```proto
message BatchGetBooksResponse {
// Books requested.
repeated Book books = 1;
}
```

- The response message **must** include one repeated field corresponding to the
resources being retrieved.

{% tab oas %}

- The response schema **must** be an array with each item containing one of the
requested resources.
mkistler marked this conversation as resolved.
Show resolved Hide resolved

{% endtabs %}

- The order of resources in the response **must** be the same as the names in
the request.

## Changelog

- **2024-04-22:** Adopt from Google AIP https://google.aip.dev/231 with the
following changes:
- Dropped the "nested requests" pattern.
mkistler marked this conversation as resolved.
Show resolved Hide resolved

<!-- Links -->

[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
[request-message]: ./0131.md#request-message
4 changes: 2 additions & 2 deletions aep/general/0231/aep.yaml
Original file line number Diff line number Diff line change
@@ -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
58 changes: 58 additions & 0 deletions aep/general/0231/batchget.oas.yaml
Original file line number Diff line number Diff line change
@@ -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.
Loading