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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
154 changes: 151 additions & 3 deletions aep/general/0231/aep.md.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,153 @@
# 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 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.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- 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 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.
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
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}
// 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 paths of the books to retrieve.
// A maximum of 1000 books can be retrieved in a batch.
// Format: publishers/{publisher}/books/{book}
repeated string paths = 2 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "library.com/Book"
}];
}
```

- 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
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
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-paths] that it
mkistler marked this conversation as resolved.
Show resolved Hide resolved
references.
- The comment for the field **should** document the resource pattern.
- The comment for the field **should** document the maximum number of
paths allowed.
mkistler marked this conversation as resolved.
Show resolved Hide resolved
- There **must not** be a body key in the `google.api.http` annotation.

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

{% 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 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The response for a batch get method **should** be specified with the following
The response for a batch get method **must** be specified with the following

Feels weird to have a should that includes multiple musts. Why not enforce the pattern?

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 paths 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-paths]: ./0122.md#fields-representing-resource-paths
[aep-122-parent]: ./0122.md#fields-representing-a-resources-parent
[aep-132]: https://aep.dev/132
[get-request]: ./0131.md#get-request
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
63 changes: 63 additions & 0 deletions aep/general/0231/batchget.oas.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
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: paths
in: query
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:
'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