Skip to content

Commit 285abae

Browse files
author
Luke Sneeringer
authored
Merge branch 'master' into aip-163
2 parents ba9c709 + d5e8f5c commit 285abae

File tree

8 files changed

+477
-1
lines changed

8 files changed

+477
-1
lines changed

.github/renovate.json5

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
extends: ['config:base', 'docker:disable'],
3+
commitMessagePrefix: 'chore: ',
4+
groupName: 'multiple dependencies',
5+
}

aip/general/0001/aip.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# AIP Purpose and Guidelines
2+
3+
Service APIs on the Internet continue to proliferate; having a machine-readable
4+
API is an expectation and prerequisite to adoption for many services. By some
5+
estimates, there are now more than 20,000 public REST APIs available.
6+
7+
As this corpus continues to grow, many companies struggle with API Governance:
8+
even as companies grow and disparate teams work to deliver discrete services,
9+
APIs ought to remain simple, intuitive, and consistent.
10+
11+
Therefore, it is increasingly necessary to have a corpus of documentation for
12+
API producers, reviewers, and other interested parties to reference. The AIP
13+
collection provides a way to provide consistent documentation for API design
14+
guidance.
15+
16+
## What is an AIP?
17+
18+
AIP stands for **API Improvement Proposal**, which is a design document
19+
providing high-level, concise documentation for API development.
20+
21+
Companies that adopt the AIP program use them as a source of truth for
22+
API-related documentation, and the means by which service producers discuss and
23+
come to consensus on API guidance. AIPs are maintained as Markdown files with
24+
metadata in the AIP GitHub repository.
25+
26+
## Adopting AIPs
27+
28+
Companies **may** adopt the AIP system in one of two ways:
29+
30+
- By applying the guidance described at [aip.dev][].
31+
- By "forking" the AIP system and setting up their own subdomain.
32+
33+
Companies with an already-established corpus of services are unlikely to have
34+
exactly followed the guidance at [aip.dev][]. Forking the system is valuable
35+
because the guidance becomes comparable. Forks **must** retain the same
36+
numbering system (AIP-2) to provide that comparability.
37+
38+
### Technical leadership
39+
40+
The AIP system, as well as the guidance on [aip.dev][], is overseen by the AIP
41+
technical steering committee. The committee is the set of people who make
42+
decisions on AIPs. The general goal is that the AIP process is collaborative
43+
and that we largely work on the basis of consensus. However, a limited number
44+
of designated approvers is necessary, and these committee members will be
45+
approvers for each AIP on [aip.dev][].
46+
47+
The technical steering committee membership is currently:
48+
49+
- Antoine Boyer (@tinnou), Netflix
50+
- Ross Hamilton (@rhamiltonsf), Salesforce
51+
- Mike Kistler (@mkistler), IBM
52+
- Luke Sneeringer (@lukesneeringer), Google
53+
54+
The committee is also responsible for the administrative and editorial aspects
55+
of shepherding AIPs and managing the AIP pipeline and workflow. They approve
56+
PRs to AIPs, assign proposal numbers, manage the agenda, set AIP states, and so
57+
forth. They also ensure that AIPs are readable (proper spelling, grammar,
58+
sentence structure, markup, etc.).
59+
60+
Committee membership is by invitation of the current committee. The committee
61+
**must not** include more than two members from the same company.
62+
63+
**Note:** Companies that maintain their own fork of [aip.dev][] select their
64+
own leadership and have full control of their fork's content.
65+
66+
## States
67+
68+
At any given time, AIPs may exist in a variety of states as they work their way
69+
through the process. The following is a summary of each state.
70+
71+
### Reviewing
72+
73+
Initial discussion on most AIPs occurs in the initial pull request to submit
74+
the AIP. Once this PR is merged, the AIP exists in the "Reviewing" state. This
75+
means that the authors and the technical steering committee have reached a
76+
general consensus on the proposal.
77+
78+
At this stage, the committee may request changes or suggest alternatives to the
79+
proposal before moving forward, but there is a general expectation that the
80+
proposal will move forward and it is usually safe to "early adopt" it.
81+
82+
An AIP **must** be in the reviewing state for at least 14 days before being
83+
approved, and the committee **should** send appropriate communication regarding
84+
the pending approval.
85+
86+
**Note:** As a formal matter, one AIP approver (other than the author) **must**
87+
provide formal signoff to advance an AIP to the reviewing state. Additionally,
88+
there **must not** be formal objections ("changes requested" on the GitHub PR)
89+
from other approvers.
90+
91+
### Approved
92+
93+
Once an AIP has been agreed upon, it enters "approved" state and is considered
94+
"best current practice".
95+
96+
AIPs **may** be edited after they are approved, either to correct grammar or
97+
word choices, or to clarify semantic guidance (in response to reader
98+
questions). In rare occasions, new guidance **may** be added.
99+
100+
Clarifications and new guidance **must** be reflected in the changelog.
101+
Correction of typos or minor language alterations **may** be done silently.
102+
103+
**Note:** As a formal matter, two AIP approvers (other than the author)
104+
**must** provide formal signoff to advance an AIP to the approved state.
105+
Additionally, there **must not** be formal objections ("changes requested" on
106+
the GitHub PR) from other approvers.
107+
108+
### Final
109+
110+
If an AIP has been approved for a significant period and the technical steering
111+
committee is certain that no further guidance will be needed, they **may** move
112+
the AIP in to "final" state.
113+
114+
AIPs in the final state **must not** be amended with new guidance. They **may**
115+
be editied to correct spelling, grammar, or clarity provided there are no
116+
semantic changes.
117+
118+
**Note:** As a formal matter, two AIP approvers **must** provide formal signoff
119+
to advance an AIP to the final state. Additionally, there **must not** be
120+
formal objections ("changes requested" on the GItHub PR) from other approvers.
121+
122+
### Replaced
123+
124+
If an AIP has been replaced by another AIP, it enters "replaced" state. The AIP
125+
**must** include a notice explaining the replacement and rationale (the
126+
replacement AIP **should** also clearly explain the rationale).
127+
128+
In general, service producers rely primarily on AIPs in the "approved" state.
129+
Service producers **may** rely on AIPs in the "reviewing" state
130+
131+
### Withdrawn
132+
133+
If an AIP is withdrawn by the author or champion, or is rejected by the
134+
technical steering committee after reaching the "reviewing" state, it enters
135+
"withdrawn" state. Withdrawn AIPs remain accessible, but are removed from the
136+
indexes; they provide documentation and reference to inform future discussions.
137+
138+
## Workflow
139+
140+
The following workflow describes the process for proposing an AIP, and moving
141+
an AIP from proposal to implementation to final acceptance.
142+
143+
### Overview
144+
145+
```graphviz
146+
digraph d_front_back {
147+
rankdir=LR;
148+
node [ style="filled,solid" shape=box fontname="Roboto" ];
149+
github_pr [ shape="oval" label="GitHub PR" fillcolor="orange" ];
150+
reviewing [ label="Reviewing" fillcolor="lightskyblue" ];
151+
approved [ label="Approved" fillcolor="palegreen" ];
152+
final [ label="Final" fillcolor="palegreen" ];
153+
withdrawn [ label="Withdrawn" fillcolor="mistyrose" ];
154+
replaced [ label="Replaced" fillcolor="lightsteelblue" ];
155+
156+
github_pr -> reviewing;
157+
reviewing -> approved;
158+
reviewing -> withdrawn [ style=dashed, color=mistyrose3 ];
159+
approved -> final;
160+
approved -> replaced [ style=dashed, color=lightsteelblue3 ];
161+
final -> replaced [ style=dashed color=lightsteelblue3 ];
162+
}
163+
```
164+
165+
### Proposing an AIP
166+
167+
In order to propose an AIP, first open a pull request with a draft AIP; the AIP
168+
should conform to the guidance in AIP-8. Most AIPs **should** be no more than
169+
two pages if printed out.
170+
171+
If the technical steering committee has suggested an AIP number, use that;
172+
otherwise use 99 (and expect to change it during the course of the review).
173+
174+
**Important:** Ensure that the PR is editable by maintainers.
175+
176+
In most circumstances, the committee will assign the proposal an AIP number and
177+
begin discussion. Once there is consensus, the committee will merge the PR, and
178+
the AIP will enter the "reviewing" state.
179+
180+
The committee **may** reject an AIP outright if they have an obvious reason to
181+
do so (e.g. the proposal was already discussed and rejected in another AIP or
182+
is fundamentally unsound), in which case the PR is not merged.
183+
184+
### Accepting an AIP
185+
186+
The editors will work together to ensure that qualified proposals do not linger
187+
in review.
188+
189+
To gain final approval, an AIP **must** be approved by, at minimum, two members
190+
of the technical steering committee. Additionally, there **should not** be any
191+
committee members requesting significant changes (indicated by the use of the
192+
"changes requested" feature on GitHub).
193+
194+
**Note:** If an AIP editor is the primary author of an AIP, then at least two
195+
_other_ editors must approve it.
196+
197+
### Withdrawing or Rejecting an AIP
198+
199+
The author of an AIP may decide, after further consideration, that an AIP
200+
should not advance. If so, the author may withdraw the AIP by updating the PR
201+
adding a notice of withdrawal with an explanation of the rationale.
202+
203+
Additionally, the author may be unable to get consensus among the group and the
204+
technical steering committee may elect to reject the AIP. In this situation,
205+
the committee shall amend the PR adding a notice of rejection with an
206+
explanation of the rationale. In both cases, the committee **must** update the
207+
state accordingly and submit the PR.
208+
209+
### Replacing an AIP
210+
211+
In rare cases, it may be necessary to replace an AIP with another one. This is
212+
not general practice: minor edits to approved AIPs are acceptable, and AIPs
213+
only enter final state when there is high confidence that further edits will
214+
not be necessary.
215+
216+
However, if new guidance fundamentally alters the old guidance in some way,
217+
then the technical steering committee **should** create a new AIP that, once
218+
approved, will replace the old one. The old one then enters "Replaced" state,
219+
and will link to the new, current AIP.
220+
221+
[aip.dev]: https://aip.dev/

aip/general/0001/aip.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
id: 1
3+
state: reviewing
4+
created: 2020-10-05
5+
placement:
6+
category: meta
7+
order: 10
8+
js_scripts:
9+
- /assets/js/graphviz/viz.js
10+
- /assets/js/graphviz/lite.render.js
11+
- /assets/js/aip/aip-graphviz.js

aip/general/0131/aip.md.j2

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# GET for individual resources
2+
3+
In REST APIs, it is customary to make a `GET` request to a resource's URI (for
4+
example, `/v1/publishers/{publisher}/books/{book}`) in order to retrieve that
5+
resource.
6+
7+
Our APIs honor this pattern by allowing `GET` requests to be sent to the
8+
resource URI, which returns the resource itself.
9+
10+
## Guidance
11+
12+
APIs **should** generally provide a `GET` method for resources unless it is not
13+
valuable for users to do so. When the `GET` method is used on a URI ending in a
14+
resource ID or resource ID alias, the result should be a single resource. For
15+
more information about using the `GET` method on a URI ending with a resource
16+
collection identifier, see AIP-132.
17+
18+
### Requests
19+
20+
Single-resource `GET` operations **must** be made by sending a `GET` request to
21+
the resource's URI:
22+
23+
```http
24+
GET /v1/publishers/{publisher}/books/{book} HTTP/2
25+
Host: library.googleapis.com
26+
Accept: application/json
27+
```
28+
29+
- The HTTP method **must** be `GET`.
30+
- The request **must** be safe and **must not** have side effects.
31+
- There **must not** be a request body.
32+
- If a `GET` request contains a body, the body **must** be ignored, and
33+
**must not** cause an error.
34+
- The request **must not** require any fields in the query string. The request
35+
**should not** include optional fields in the query string unless described
36+
in another AIP.
37+
38+
### Responses
39+
40+
Single-resource `GET` operations **must** return the resource itself, without
41+
any additional wrapping:
42+
43+
```json
44+
{
45+
"name": "publishers/lacroix/books/les-mis",
46+
"isbn": "978-037-540317-0",
47+
"title": "Les Misérables",
48+
"authors": ["Victor Hugo"],
49+
"rating": 9.6
50+
}
51+
```
52+
53+
### Errors
54+
55+
If the user does not have sufficient permission to know that the resource
56+
exists, the service **should** reply with an HTTP 404 error, regardless of
57+
whether or not the resource exists. Permission **must** be checked prior to
58+
checking if the resource exists.
59+
60+
If the user has sufficient permission to know that the resource exists, but is
61+
unable to access it, the service **should** reply with an HTTP 403 error.
62+
63+
If the user does have proper permission, but the requested resource does not
64+
exist, the service **must** reply with an HTTP 404 error.
65+
66+
## Interface Definitions
67+
68+
{% tab proto -%}
69+
70+
Get operations are specified using the following pattern:
71+
72+
{% sample 'get.proto', 'rpc GetBook' %}
73+
74+
- The RPC's name **must** begin with the word `Get`. The remainder of the RPC
75+
name **should** be the singular form of the resource's message name.
76+
- The request message **must** match the RPC name, with a `-Request` suffix.
77+
- The response message **must** be the resource itself. (There is no
78+
`GetBookResponse`.)
79+
- The response **should** usually include the fully-populated resource unless
80+
there is a reason to return a partial response (see AIP-157).
81+
- The HTTP verb **must** be `GET`.
82+
- The URI **should** contain a single variable field corresponding to the
83+
resource name.
84+
- This field **should** be called `name`.
85+
- The URI **should** have a variable corresponding to this field.
86+
- The `name` field **should** be the only variable in the URI path. All
87+
remaining parameters **should** map to URI query parameters.
88+
- There **must not** be a `body` key in the `google.api.http` annotation.
89+
- There **should** be exactly one `google.api.method_signature` annotation,
90+
with a value of `"name"`.
91+
92+
Get operations also implement a common request message pattern:
93+
94+
{% sample 'get.proto', 'message GetBookRequest' %}
95+
96+
- A resource name field **must** be included. It **should** be called `name`.
97+
- The field **should** be annotated as required.
98+
- The field **should** identify the [resource type][aip-123] that it
99+
references.
100+
- The comment for the `name` field **should** document the resource pattern.
101+
- The request message **must not** contain any other required fields, and
102+
**should not** contain other optional fields except those described in
103+
another AIP.
104+
105+
**Note:** The `name` field in the request object corresponds to the `name`
106+
variable in the `google.api.http` annotation on the RPC. This causes the `name`
107+
field in the request to be populated based on the value in the URL when the
108+
REST/JSON interface is used.
109+
110+
{% tab oas %}
111+
112+
Single-resource `GET` operations **must** be specified with consistent OpenAPI
113+
metadata:
114+
115+
{% sample 'get.oas.yaml', 'paths' %}
116+
117+
- The `operationId` **must** begin with the word `get`. The remainder of the
118+
`operationId` **should** be the singular form of the resource type's name.
119+
- The response content **must** be the resource itself. For example:
120+
`#/components/schemas/Book`
121+
- The response **should** usually include the fully-populated resource unless
122+
there is a reason to return a partial response (see AIP-157).
123+
- The URI **should** contain a variable for each individual ID in the resource
124+
hierarchy.
125+
- The path parameter for all resource IDs **must** be in the form
126+
`{resourceName}Id` (such as `bookId`), and path parameters representing the
127+
ID of parent resources **must** end with `Id`.
128+
129+
{% endtabs %}

aip/general/0131/aip.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
id: 131
3+
state: approved
4+
created: 2019-01-22
5+
placement:
6+
category: operations
7+
order: 10

0 commit comments

Comments
 (0)