-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
477 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
extends: ['config:base', 'docker:disable'], | ||
commitMessagePrefix: 'chore: ', | ||
groupName: 'multiple dependencies', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
# AIP Purpose and Guidelines | ||
|
||
Service APIs on the Internet continue to proliferate; having a machine-readable | ||
API is an expectation and prerequisite to adoption for many services. By some | ||
estimates, there are now more than 20,000 public REST APIs available. | ||
|
||
As this corpus continues to grow, many companies struggle with API Governance: | ||
even as companies grow and disparate teams work to deliver discrete services, | ||
APIs ought to remain simple, intuitive, and consistent. | ||
|
||
Therefore, it is increasingly necessary to have a corpus of documentation for | ||
API producers, reviewers, and other interested parties to reference. The AIP | ||
collection provides a way to provide consistent documentation for API design | ||
guidance. | ||
|
||
## What is an AIP? | ||
|
||
AIP stands for **API Improvement Proposal**, which is a design document | ||
providing high-level, concise documentation for API development. | ||
|
||
Companies that adopt the AIP program use them as a source of truth for | ||
API-related documentation, and the means by which service producers discuss and | ||
come to consensus on API guidance. AIPs are maintained as Markdown files with | ||
metadata in the AIP GitHub repository. | ||
|
||
## Adopting AIPs | ||
|
||
Companies **may** adopt the AIP system in one of two ways: | ||
|
||
- By applying the guidance described at [aip.dev][]. | ||
- By "forking" the AIP system and setting up their own subdomain. | ||
|
||
Companies with an already-established corpus of services are unlikely to have | ||
exactly followed the guidance at [aip.dev][]. Forking the system is valuable | ||
because the guidance becomes comparable. Forks **must** retain the same | ||
numbering system (AIP-2) to provide that comparability. | ||
|
||
### Technical leadership | ||
|
||
The AIP system, as well as the guidance on [aip.dev][], is overseen by the AIP | ||
technical steering committee. The committee is the set of people who make | ||
decisions on AIPs. The general goal is that the AIP process is collaborative | ||
and that we largely work on the basis of consensus. However, a limited number | ||
of designated approvers is necessary, and these committee members will be | ||
approvers for each AIP on [aip.dev][]. | ||
|
||
The technical steering committee membership is currently: | ||
|
||
- Antoine Boyer (@tinnou), Netflix | ||
- Ross Hamilton (@rhamiltonsf), Salesforce | ||
- Mike Kistler (@mkistler), IBM | ||
- Luke Sneeringer (@lukesneeringer), Google | ||
|
||
The committee is also responsible for the administrative and editorial aspects | ||
of shepherding AIPs and managing the AIP pipeline and workflow. They approve | ||
PRs to AIPs, assign proposal numbers, manage the agenda, set AIP states, and so | ||
forth. They also ensure that AIPs are readable (proper spelling, grammar, | ||
sentence structure, markup, etc.). | ||
|
||
Committee membership is by invitation of the current committee. The committee | ||
**must not** include more than two members from the same company. | ||
|
||
**Note:** Companies that maintain their own fork of [aip.dev][] select their | ||
own leadership and have full control of their fork's content. | ||
|
||
## States | ||
|
||
At any given time, AIPs may exist in a variety of states as they work their way | ||
through the process. The following is a summary of each state. | ||
|
||
### Reviewing | ||
|
||
Initial discussion on most AIPs occurs in the initial pull request to submit | ||
the AIP. Once this PR is merged, the AIP exists in the "Reviewing" state. This | ||
means that the authors and the technical steering committee have reached a | ||
general consensus on the proposal. | ||
|
||
At this stage, the committee may request changes or suggest alternatives to the | ||
proposal before moving forward, but there is a general expectation that the | ||
proposal will move forward and it is usually safe to "early adopt" it. | ||
|
||
An AIP **must** be in the reviewing state for at least 14 days before being | ||
approved, and the committee **should** send appropriate communication regarding | ||
the pending approval. | ||
|
||
**Note:** As a formal matter, one AIP approver (other than the author) **must** | ||
provide formal signoff to advance an AIP to the reviewing state. Additionally, | ||
there **must not** be formal objections ("changes requested" on the GitHub PR) | ||
from other approvers. | ||
|
||
### Approved | ||
|
||
Once an AIP has been agreed upon, it enters "approved" state and is considered | ||
"best current practice". | ||
|
||
AIPs **may** be edited after they are approved, either to correct grammar or | ||
word choices, or to clarify semantic guidance (in response to reader | ||
questions). In rare occasions, new guidance **may** be added. | ||
|
||
Clarifications and new guidance **must** be reflected in the changelog. | ||
Correction of typos or minor language alterations **may** be done silently. | ||
|
||
**Note:** As a formal matter, two AIP approvers (other than the author) | ||
**must** provide formal signoff to advance an AIP to the approved state. | ||
Additionally, there **must not** be formal objections ("changes requested" on | ||
the GitHub PR) from other approvers. | ||
|
||
### Final | ||
|
||
If an AIP has been approved for a significant period and the technical steering | ||
committee is certain that no further guidance will be needed, they **may** move | ||
the AIP in to "final" state. | ||
|
||
AIPs in the final state **must not** be amended with new guidance. They **may** | ||
be editied to correct spelling, grammar, or clarity provided there are no | ||
semantic changes. | ||
|
||
**Note:** As a formal matter, two AIP approvers **must** provide formal signoff | ||
to advance an AIP to the final state. Additionally, there **must not** be | ||
formal objections ("changes requested" on the GItHub PR) from other approvers. | ||
|
||
### Replaced | ||
|
||
If an AIP has been replaced by another AIP, it enters "replaced" state. The AIP | ||
**must** include a notice explaining the replacement and rationale (the | ||
replacement AIP **should** also clearly explain the rationale). | ||
|
||
In general, service producers rely primarily on AIPs in the "approved" state. | ||
Service producers **may** rely on AIPs in the "reviewing" state | ||
|
||
### Withdrawn | ||
|
||
If an AIP is withdrawn by the author or champion, or is rejected by the | ||
technical steering committee after reaching the "reviewing" state, it enters | ||
"withdrawn" state. Withdrawn AIPs remain accessible, but are removed from the | ||
indexes; they provide documentation and reference to inform future discussions. | ||
|
||
## Workflow | ||
|
||
The following workflow describes the process for proposing an AIP, and moving | ||
an AIP from proposal to implementation to final acceptance. | ||
|
||
### Overview | ||
|
||
```graphviz | ||
digraph d_front_back { | ||
rankdir=LR; | ||
node [ style="filled,solid" shape=box fontname="Roboto" ]; | ||
github_pr [ shape="oval" label="GitHub PR" fillcolor="orange" ]; | ||
reviewing [ label="Reviewing" fillcolor="lightskyblue" ]; | ||
approved [ label="Approved" fillcolor="palegreen" ]; | ||
final [ label="Final" fillcolor="palegreen" ]; | ||
withdrawn [ label="Withdrawn" fillcolor="mistyrose" ]; | ||
replaced [ label="Replaced" fillcolor="lightsteelblue" ]; | ||
github_pr -> reviewing; | ||
reviewing -> approved; | ||
reviewing -> withdrawn [ style=dashed, color=mistyrose3 ]; | ||
approved -> final; | ||
approved -> replaced [ style=dashed, color=lightsteelblue3 ]; | ||
final -> replaced [ style=dashed color=lightsteelblue3 ]; | ||
} | ||
``` | ||
|
||
### Proposing an AIP | ||
|
||
In order to propose an AIP, first open a pull request with a draft AIP; the AIP | ||
should conform to the guidance in AIP-8. Most AIPs **should** be no more than | ||
two pages if printed out. | ||
|
||
If the technical steering committee has suggested an AIP number, use that; | ||
otherwise use 99 (and expect to change it during the course of the review). | ||
|
||
**Important:** Ensure that the PR is editable by maintainers. | ||
|
||
In most circumstances, the committee will assign the proposal an AIP number and | ||
begin discussion. Once there is consensus, the committee will merge the PR, and | ||
the AIP will enter the "reviewing" state. | ||
|
||
The committee **may** reject an AIP outright if they have an obvious reason to | ||
do so (e.g. the proposal was already discussed and rejected in another AIP or | ||
is fundamentally unsound), in which case the PR is not merged. | ||
|
||
### Accepting an AIP | ||
|
||
The editors will work together to ensure that qualified proposals do not linger | ||
in review. | ||
|
||
To gain final approval, an AIP **must** be approved by, at minimum, two members | ||
of the technical steering committee. Additionally, there **should not** be any | ||
committee members requesting significant changes (indicated by the use of the | ||
"changes requested" feature on GitHub). | ||
|
||
**Note:** If an AIP editor is the primary author of an AIP, then at least two | ||
_other_ editors must approve it. | ||
|
||
### Withdrawing or Rejecting an AIP | ||
|
||
The author of an AIP may decide, after further consideration, that an AIP | ||
should not advance. If so, the author may withdraw the AIP by updating the PR | ||
adding a notice of withdrawal with an explanation of the rationale. | ||
|
||
Additionally, the author may be unable to get consensus among the group and the | ||
technical steering committee may elect to reject the AIP. In this situation, | ||
the committee shall amend the PR adding a notice of rejection with an | ||
explanation of the rationale. In both cases, the committee **must** update the | ||
state accordingly and submit the PR. | ||
|
||
### Replacing an AIP | ||
|
||
In rare cases, it may be necessary to replace an AIP with another one. This is | ||
not general practice: minor edits to approved AIPs are acceptable, and AIPs | ||
only enter final state when there is high confidence that further edits will | ||
not be necessary. | ||
|
||
However, if new guidance fundamentally alters the old guidance in some way, | ||
then the technical steering committee **should** create a new AIP that, once | ||
approved, will replace the old one. The old one then enters "Replaced" state, | ||
and will link to the new, current AIP. | ||
|
||
[aip.dev]: https://aip.dev/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
id: 1 | ||
state: reviewing | ||
created: 2020-10-05 | ||
placement: | ||
category: meta | ||
order: 10 | ||
js_scripts: | ||
- /assets/js/graphviz/viz.js | ||
- /assets/js/graphviz/lite.render.js | ||
- /assets/js/aip/aip-graphviz.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# GET for individual resources | ||
|
||
In REST APIs, it is customary to make a `GET` request to a resource's URI (for | ||
example, `/v1/publishers/{publisher}/books/{book}`) in order to retrieve that | ||
resource. | ||
|
||
Our APIs honor this pattern by allowing `GET` requests to be sent to the | ||
resource URI, which returns the resource itself. | ||
|
||
## Guidance | ||
|
||
APIs **should** generally provide a `GET` method for resources unless it is not | ||
valuable for users to do so. When the `GET` method is used on a URI ending in a | ||
resource ID or resource ID alias, the result should be a single resource. For | ||
more information about using the `GET` method on a URI ending with a resource | ||
collection identifier, see AIP-132. | ||
|
||
### Requests | ||
|
||
Single-resource `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.googleapis.com | ||
Accept: application/json | ||
``` | ||
|
||
- The HTTP method **must** be `GET`. | ||
- The request **must** be safe and **must not** have side effects. | ||
- 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 request **must not** require any fields in the query string. The request | ||
**should not** include optional fields in the query string unless described | ||
in another AIP. | ||
|
||
### Responses | ||
|
||
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 | ||
} | ||
``` | ||
|
||
### Errors | ||
|
||
If the user does not have sufficient permission to know that the resource | ||
exists, the service **should** reply with an HTTP 404 error, regardless of | ||
whether or not the resource exists. Permission **must** be checked prior to | ||
checking if the resource exists. | ||
|
||
If the user has sufficient permission to know that the resource exists, but is | ||
unable to access it, the service **should** reply with an HTTP 403 error. | ||
|
||
If the user does have proper permission, but the requested resource does not | ||
exist, the service **must** reply with an HTTP 404 error. | ||
|
||
## Interface Definitions | ||
|
||
{% tab proto -%} | ||
|
||
Get operations are specified using the following pattern: | ||
|
||
{% sample 'get.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 response **should** usually include the fully-populated resource unless | ||
there is a reason to return a partial response (see AIP-157). | ||
- The HTTP verb **must** be `GET`. | ||
- The URI **should** contain a single variable field corresponding to the | ||
resource name. | ||
- This field **should** be called `name`. | ||
- The URI **should** have a variable corresponding to this field. | ||
- The `name` 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 `"name"`. | ||
|
||
Get operations also implement a common request message pattern: | ||
|
||
{% sample 'get.proto', 'message GetBookRequest' %} | ||
|
||
- A resource name field **must** be included. It **should** be called `name`. | ||
- The field **should** be annotated as required. | ||
- The field **should** identify the [resource type][aip-123] that it | ||
references. | ||
- The comment for the `name` 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 AIP. | ||
|
||
**Note:** The `name` field in the request object corresponds to the `name` | ||
variable in the `google.api.http` annotation on the RPC. This causes the `name` | ||
field in the request to be populated based on the value in the URL when the | ||
REST/JSON interface is used. | ||
|
||
{% 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 **should** usually include the fully-populated resource unless | ||
there is a reason to return a partial response (see AIP-157). | ||
- 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`. | ||
|
||
{% endtabs %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
id: 131 | ||
state: approved | ||
created: 2019-01-22 | ||
placement: | ||
category: operations | ||
order: 10 |
Oops, something went wrong.