Skip to content

Commit

Permalink
feat(132-135): standardize on a format for standard methods
Browse files Browse the repository at this point in the history
The standard method AEPs have a bit of inconsistency
in the format and the examples they provide.

This PR proposes a format to normalize them all to, including
the following headings:

- Overview: a brief explanation of the method
- Guidance: a brief explanation of the purpose
  - Operation: an example operation, with must/should guidance
  - Request: an example request, with must/should guidance
  - Response: an example request, with must/should guidance
  - Errors: explanation on errors, if applicable
  - (additional guidance sections specific to the AEP)
- Interface Definitions: a full example of the operation, request, and response.

This will result in some incomplete sections: those will be filled out via
follow-up PRs to keep this from becoming too massive.
  • Loading branch information
toumorokoshi committed Nov 9, 2024
1 parent cc9c261 commit 3742019
Show file tree
Hide file tree
Showing 15 changed files with 1,017 additions and 700 deletions.
142 changes: 76 additions & 66 deletions aep/general/0131/aep.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,72 @@ resource.
is to return data from a single resource.
- Some resources take longer to be retrieved than is reasonable for a regular API request. In this situation, the API should use a [long-running operation](/long-running-operations).

### Requests
### Operation

{% tab proto %}

{% sample '../example.proto', 'rpc GetBook' %}

- The RPC's name **must** begin with the word `Get`. The remainder of the RPC
name **should** be the singular form of the resource's message name.
- The request message **must** match the RPC name, with a `Request` suffix.
- The response message **must** be the resource itself. (There is no
`GetBookResponse`.)
- The HTTP verb **must** be `GET`.
- The URI **should** contain a single variable field corresponding to the
resource path.
- This field **should** be called `path`.
- The URI **should** have a variable corresponding to this field.
- The `path` field **should** be the only variable in the URI path. All
remaining parameters **should** map to URI query parameters.
- There **must not** be a `body` key in the `google.api.http` annotation.
- There **should** be exactly one `google.api.method_signature` annotation,
with a value of `"path"`.

{% tab oas %}

`Get` operations **must** be made by sending a `GET` request to the resource's
URI:

```http
GET /v1/publishers/{publisher}/books/{book} HTTP/2
Host: library.example.com
Host: bookstore.example.com
Accept: application/json
```

- The URI **should** contain a variable for each resource in the resource
hierarchy.
- The path parameter for all resource IDs **must** be in the form
`{resource-singular}` (such as `book`).

{% endtabs %}

### Requests

{% tab proto %}

{% sample '../example.proto', 'message GetBookRequest' %}

- A resource path field **must** be included. It **should** be called `path`.
- The field **should** be annotated as `REQUIRED`.
- The field **should** identify the [resource type][aep-4] that it
references.
- The comment for the `path` field **should** document the resource pattern.
- The request message **must not** contain any other required fields, and
**should not** contain other optional fields except those described in
another AEP.

**Note:** The `path` field in the request object corresponds to the `path`
variable in the `google.api.http` annotation on the RPC. This causes the `path`
field in the request to be populated based on the value in the URL when the
REST/JSON interface is used.

[aep-4]: ./0004.md

{% tab oas %}

{% sample '../example.oas.yaml', '$.paths./publishers/{publisher}/books/{book}.get.parameters' %}

- The HTTP method **must** be `GET`.
- The request **must** be safe and **must not** have side effects.
- There **must not** be a request body.
Expand All @@ -34,24 +89,26 @@ Accept: application/json
**should not** include optional fields in the query string unless described
in another AEP.

### Responses
{% endtabs %}

Single-resource `GET` operations **must** return the resource itself, without
any additional wrapping:

```json
{
"name": "publishers/lacroix/books/les-mis",
"isbn": "978-037-540317-0",
"title": "Les Misérables",
"authors": ["Victor Hugo"],
"rating": 9.6
}
```
### Responses

The response **should** usually include the fully-populated resource unless
there is a reason to return a partial response (see AEP-157).

{% tab proto %}

{% sample '../example.proto', 'message Book' %}

{% tab oas %}

{% sample '../example.oas.yaml', '$.paths./publishers/{publisher}/books/{book}.get.responses.200.content' %}

- The response content **must** be the resource itself. For example:
`#/components/schemas/Book`. The response **must** reference a schema with a `x-aep-resource` extension.

{% endtabs %}

### Errors

If the user does not have sufficient permission to know that the resource
Expand All @@ -69,61 +126,14 @@ exist, the service **must** reply with an HTTP 404 error.

{% tab proto -%}

Get operations are specified using the following pattern:
{% sample '../example.proto', 'rpc GetBook' %}

{% sample 'get.proto', 'rpc GetBook' %}
{% sample '../example.proto', 'message GetBookRequest' %}

- The RPC's name **must** begin with the word `Get`. The remainder of the RPC
name **should** be the singular form of the resource's message name.
- The request message **must** match the RPC name, with a `Request` suffix.
- The response message **must** be the resource itself. (There is no
`GetBookResponse`.)
- The HTTP verb **must** be `GET`.
- The URI **should** contain a single variable field corresponding to the
resource path.
- This field **should** be called `path`.
- The URI **should** have a variable corresponding to this field.
- The `path` field **should** be the only variable in the URI path. All
remaining parameters **should** map to URI query parameters.
- There **must not** be a `body` key in the `google.api.http` annotation.
- There **should** be exactly one `google.api.method_signature` annotation,
with a value of `"path"`.

Get operations also implement a common request message pattern:

{% sample 'get.proto', 'message GetBookRequest' %}

- A resource path field **must** be included. It **should** be called `path`.
- The field **should** be annotated as `REQUIRED`.
- The field **should** identify the [resource type][aep-4] that it
references.
- The comment for the `path` field **should** document the resource pattern.
- The request message **must not** contain any other required fields, and
**should not** contain other optional fields except those described in
another AEP.

**Note:** The `path` field in the request object corresponds to the `path`
variable in the `google.api.http` annotation on the RPC. This causes the `path`
field in the request to be populated based on the value in the URL when the
REST/JSON interface is used.

[aep-4]: ./0004.md
{% sample '../example.proto', 'message Book' %}

{% tab oas %}

Single-resource `GET` operations **must** be specified with consistent OpenAPI
metadata:

{% sample 'get.oas.yaml', 'paths' %}

- The `operationId` **must** begin with the word `get`. The remainder of the
`operationId` **should** be the singular form of the resource type's name.
- The response content **must** be the resource itself. For example:
`#/components/schemas/Book`. The response **must** reference a schema with a `x-aep-resource` extension.
- The URI **should** contain a variable for each individual ID in the resource
hierarchy.
- The path parameter for all resource IDs **must** be in the form
`{resourceName}Id` (such as `bookId`), and path parameters representing the
ID of parent resources **must** end with `Id`.
{% sample '../example.oas.yaml', '$.paths./publishers/{publisher}/books/{book}.get' %}

{% endtabs %}
52 changes: 0 additions & 52 deletions aep/general/0131/get.oas.yaml

This file was deleted.

64 changes: 0 additions & 64 deletions aep/general/0131/get.proto

This file was deleted.

Loading

0 comments on commit 3742019

Please sign in to comment.