Skip to content

Commit

Permalink
Merge branch 'master' into patch-3
Browse files Browse the repository at this point in the history
  • Loading branch information
noahdietz authored Dec 11, 2024
2 parents 5f51174 + 46794fe commit 29ac99c
Show file tree
Hide file tree
Showing 29 changed files with 1,066 additions and 496 deletions.
53 changes: 53 additions & 0 deletions aip/client-libraries/4236.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
id: 4236
state: reviewing
created: 2024-05-16
---

# Version-aware clients

APIs can annotate services with [`google.api.api_version`][]. If
`google.api.api_version` is specified, version-aware clients **must**
include the value of `google.api.api_version` in the request to the API.

### Expected Generator and Client Library Behavior

If a service is annotated with `google.api.api_version`, client library
generators **must** include either an HTTP query parameter `$apiVersion`
or HTTP header `X-Goog-Api-Version`, but a request **must not** contain both.

Generated documentation for a given service **may** include the value of
`google.api.api_version`, if it exists in the source protos.

Clients **must** treat the value of `google.api.api_version` as opaque to ensure
robust compatibility. This means that the specific format or structure of the
version string **must not** be parsed or interpreted for any purpose beyond identifying
the intended API version.

## Rationale

### Necessity for Versioning

Explicit API versioning using the `google.api.api_version` annotation is essential
for maintaining compatibility between clients and services over time. As services
evolve, their schemas and behaviors may change. By specifying the API version, a
client communicates its expectations to the service. This allows the service to
respond in a manner consistent with the client's understanding, preventing errors
or unexpected results due to incompatible changes.

### Importance of Opaque Treatment

Treating the `google.api.api_version` value as opaque is important for ensuring robust
compatibility guarantees. By relying on this opaque identifier, clients avoid making
assumptions about the underlying versioning scheme, which may change independently of
the API itself. This flexibility allows service providers to evolve their versioning
strategies without impacting client compatibility.

### Mutual Exclusivity of Query and Header

Both the query parameter and header mechanisms exist to provide flexibility for different
client environments. However, allowing both simultaneously could lead to ambiguity if the
values differ. To ensure consistent version identification and prevent potential conflicts,
only one mechanism should be used at a time.

[`google.api.api_version`]: https://github.com/googleapis/googleapis/blob/master/google/api/client.proto
15 changes: 3 additions & 12 deletions aip/general/0001.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,6 @@ digraph d_front_back {
}
```

### Technical leads

The current TL (technical lead) for APIs is Eric Brewer; he has delegated some
responsibilities for API Design to the API Design TL (Andrei Scripniciuc
([@andreisc][])).

As noted in the diagram above, the TL is the final decision-maker on the AIP
process and the final point of escalation if necessary.

Expand All @@ -86,14 +80,12 @@ and these Googlers will be approvers for each AIP in the general scope.

The list of AIP editors is currently:

- Andrei Scripniciuc ([@andrei-scripniciuc][])
- Angie Lin ([@alin04][])
- Brian Grant ([@bgrant0607][])
- Hami Asaadi ([@hrasadi][])
- Jon Skeet ([@jskeet][])
- Jose Juan Zavala Iglesias ([@itsStrobe][])
- Louis Dejardin ([@loudej][])
- Noah Dietz ([@noahdietz][])
- Sam Levenick ([@slevenick][])
- Sam Woodard ([@shwoodard][])

The editors are also responsible for the administrative and editorial aspects
Expand Down Expand Up @@ -270,6 +262,7 @@ state, and will link to the new, current AIP.

## Changelog

- **2024-09-04**: Updated names of current editors and remove TLs.
- **2023-05-10**: Updated names of current and editors and TLs.
- **2019-07-30**: Further clarified AIP quorum requirements.
- **2019-05-12**: Collapsed AIP approvers and editors into a single position,
Expand All @@ -280,11 +273,9 @@ state, and will link to the new, current AIP.
[aip github repository]: https://github.com/googleapis/aip
[open an issue]: https://github.com/googleapis/aip/issues
[@alin04]:https://github.com/alin04
[@bgrant0607]: https://github.com/bgrant0607
[@hrasadi]: https://github.com/hrasadi
[@jskeet]: https://github.com/jskeet
[@loudej]: https://github.com/loudej
[@noahdietz]: https://github.com/noahdietz
[@slevenick]: https://github.com/slevenick
[@shwoodard]: https://github.com/shwoodard
[@andrei-scripniciuc]: https://github.com/andrei-scripniciuc
[@itsStrobe]: https://github.com/itsStrobe
8 changes: 7 additions & 1 deletion aip/general/0009.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ Requests. One API Service may have multiple API Service Endpoints, such as
Refers to the logical identifier of an API Service. Google APIs use RFC 1035 DNS
compatible names as their API Service Names, such as `pubsub.googleapis.com`.

### API Title

Refers to the user-facing product title of an API service, such as "Cloud Pub/Sub
API".

### API Request

A single invocation of an API Method. It is often used as the unit for billing,
Expand Down Expand Up @@ -156,6 +161,7 @@ organizations separate from those that consume them.

## Changelog

- **2024-10-23**: Add API Title entry
- **2023-07-24**: Rename IaC to Declarative Clients
- **2023-04-01**: Adding definition of IaC
- **2023-03-24**: Reformatting content to include anchor links.
- **2023-03-24**: Reformatting content to include anchor links.
2 changes: 1 addition & 1 deletion aip/general/0100.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ A few tips:

### ...if one of my API reviewers is unresponsive?

Reach out to the reviewer on Hangouts. If that fails, reach out to the other
Reach out to the reviewer on Chat. If that fails, reach out to the other
reviewer, who will coordinate accordingly. If that fails also, escalate
according to [AIP-1][].

Expand Down
35 changes: 19 additions & 16 deletions aip/general/0121.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ If the request to or the response from a standard method (or a custom method in
the same *service*) **is** the resource or **contains** the resource, the
resource schema for that resource across all methods **must** be the same.

| Standard method | Request | Response |
| --------------- | --------------------- | --------------- |
| Create | Contains the resource | Is the resource |
| Get | None | Is the resource |
| Update | Contains the resource | Is the resource |
| Delete | None | None |
| List | None | Is the resource |
| Standard method | Request | Response |
| --------------- | --------------------- | ---------------------- |
| Create | Contains the resource | Is the resource |
| Get | None | Is the resource |
| Update | Contains the resource | Is the resource |
| Delete | None | None |
| List | None | Contains the resources |

*The table above describes each standard method's relationship to the resource,
where "None" indicates that the resource neither **is** nor **is contained** in
Expand All @@ -97,16 +97,16 @@ patterns, such as database transactions, import and export, or data analysis.
### Strong Consistency

For methods that operate on the [management plane][], the completion of those
operations (either successful or with an error, LRO or synchronous) **must**
mean that the state of the resource's existence and all user-settable values
have reached a steady-state.
operations (either successful or with an error, long-running operation, or
synchronous) **must** mean that the state of the resource's existence and all
user-settable values have reached a steady-state.

[output only][] values unrelated to the resource [state][] **should** also have
reached a steady-state. for values that are related to the resource [state][].
reached a steady-state for values that are related to the resource [state][].

Examples include:

- Following a successful create that is is latest mutation on a resource, a get
- Following a successful create that is the latest mutation on a resource, a get
request for a resource **must** return the resource.
- Following a successful update that is the latest mutation on a resource, a get
request for a resource **must** return the final values from the update
Expand Down Expand Up @@ -142,9 +142,10 @@ have sole responsibility and authority for maintaining the application state.

### Cyclic References

The relationship between resources, such as parent-child or
[resource references][], **must** be representable via a
[directed acyclic graph][].
The relationship between resources, such as with [resource references][],
**must** be representable via a [directed acyclic graph][]. The parent-child
relationship also **must** be acyclic, and as per [AIP-124][] a given resource
instance will only have one canonical parent resource.

A cyclic relationship between resources increases the complexity of managing
resources. Consider resources A and B that refer to
Expand All @@ -161,6 +162,7 @@ This requirement does not apply to relationships that are expressed via
[output only][] fields, as they do not require the user to specify the values
and in turn do not increase resource management complexity.

[AIP-124]: ./0124.md
[create]: ./0133.md
[custom methods]: ./0136.md
[delete]: ./0135.md
Expand All @@ -181,10 +183,11 @@ and in turn do not increase resource management complexity.

## Changelog

- **2024-07-08**: Clarify acyclic nature of parent-child relationship.
- **2023-08-24**: Added guidance on consistency guarantees of methods.
- **2023-07-23**: Clarify stateless protocol definition.
- **2023-01-21**: Explicitly require matching schema across standard methods.
- **2022-12-19**: Added a section requiring Get and List.
- **2022-11-02**: Added a section restricting resource references.
- **2019-08-01**: Changed the examples from "shelves" to "publishers", to
present a better example of resource ownership.
present a better example of resource ownership.
55 changes: 52 additions & 3 deletions aip/general/0122.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,28 @@ An API **should** use the less-redundant form:
users/vhugo1802/events/birthday-dinner-226
```

In this situation, the _message_ is still called `UserEvent`; only the resource
name is shortened.
In this situation, the _message_ and _resource type_ are still called
`UserEvent`; only the collection and resource identifiers in the pattern(s) are
shortened. Since the _resource type_ is not shortened, the `singular` and
`plural` are similarly _not shortened_.

```
message UserEvent {
option (google.api.resource) = {
type: "example.googleapis.com/UserEvent"
// Only the collection & resource identfiers in the `pattern` are shortened.
pattern: "projects/{project}/users/{user}/events/{event}"
singular: "userEvent"
plural: "userEvents"
};
string name = 1;
}
```

**Note:** APIs wishing to do this **must** follow this format consistently
throughout the API, or else not at all.
throughout all of its `pattern` entries defined and anywhere else the
resource is referenced in the API, or else not at all.

### Resource ID segments

Expand Down Expand Up @@ -335,6 +352,34 @@ message Book {

## Rationale

### Using names instead of IDs

For any large system, there are many kinds of resources. To use simple resource
IDs to identify a resource, we'd actually need use a resource-specific tuple to
reliably identify it, such as `(bucket, object)` or `(user, album, photo)`. This
creates several issues:

* Developers have to understand and remember such anonymous tuples.
* Passing tuples is generally harder than passing strings.
* Centralized infrastructures, such as logging and access control systems,
don't understand specialized tuples.
* Specialized tuples limit API design flexibility, such as providing
reusable API interfaces. For example,
[Long Running Operations][aip-151] can work with many other API interfaces
because they use flexible resource names.

[aip-151]: ./0151.md

### Standardizing on `name`

The concept of resource names is not a new one, and is formalized in Uniform
Resource Names (URN) in conjunction with Uniform Resource Identifiers (URI) and
Uniform Resource Locators (URL). Considering that the term "name" is so heavily
overloaded in general, usage outside of a very well-defined meaning would be
confusing for developers. So, the field name `name` is reserved in the context
of AIP-compliant APIs so as to eliminate any confusion with resource names, and
force other would be "name" fields to use a more specific field name.

### Disallow embedding of resources

Using a resource message directly as the type of a field within another resource
Expand All @@ -357,6 +402,10 @@ isolation of logical concerns per-resource.

## Changelog

- **2024-10-15**: Add some rationale we found for use of `name` as a field and
instead of IDs as an identifier.
- **2024-06-14**: Clarify resource annotation shortening rules for nested
collections.
- **2023-09-19**: Prohibit duplicate collection identifiers.
- **2023-09-01**: Add a clause that allows embedding for revision resource
messages.
Expand Down
20 changes: 13 additions & 7 deletions aip/general/0123.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ placement:

Most APIs expose _resources_ (their primary nouns) which users are able to
create, retrieve, and manipulate. APIs are allowed to name their resource types
as they see fit, and are only required to ensure uniqueness within that API.
This means that it is possible (and often desirable) for different APIs to use
the same type name. For example, a Memcache and Redis API would both want to
use `Instance` as a type name.
reasonably freely (within the requirements of this AIP), and are only required
to ensure uniqueness within that API. This means that it is possible (and often
desirable) for different APIs to use the same type name. For example, a Memcache
and Redis API would both want to use `Instance` as a type name.

When mapping the relationships between APIs and their resources, however, it
becomes important to have a single, globally-unique type name. Additionally,
Expand Down Expand Up @@ -78,6 +78,10 @@ message Topic {
- Pattern variables **must** be unique within any given pattern. (e.g.
`projects/{abc}/topics/{abc}` is invalid; this is usually a natural
corollary of collection identifiers being unique within a pattern.)
- Resources with [multiple patterns][multi-pattern-resources] **must**
preserve ordering: new patterns **must** be added at the end of the list, and
existing patterns **must not** be removed or re-ordered, as this breaks client
library backward compatibility.
- Singular **must** be the lower camel case of the type.
- Pattern variables **must** be the singular form of the resource type e.g.
a pattern variable representing a `Topic` resource ID is named `{topic}`.
Expand Down Expand Up @@ -110,6 +114,7 @@ such as UpperCamelCase and snake_case.

<!-- prettier-ignore-start -->
[aip-122]: ./0122.md
[multi-pattern-resources]: https://google.aip.dev/client-libraries/4231#multi-pattern-resources
[API Group]: https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups
[nested collections]: ./0122.md#collection-identifiers
[Object]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds
Expand All @@ -119,9 +124,10 @@ such as UpperCamelCase and snake_case.

## Changelog

- **2023-09-19**: Prohibit duplicate pattern variables.
- **2023-05-06**: Adding requirement of singular and plural.
- **2023-01-28**: Clarifying guidance for the resource type name.
- **2024-08-07**: Added multi-pattern ordering compatibility requirements.
- **2023-09-19**: Prohibited duplicate pattern variables.
- **2023-05-06**: Added requirement of singular and plural.
- **2023-01-28**: Clarified guidance for the resource type name.
- **2022-10-28**: Added pattern variable format guidance.
- **2020-05-14**: Added pattern uniqueness.
- **2019-12-05**: Added guidance on patterns.
Expand Down
11 changes: 5 additions & 6 deletions aip/general/0129.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ means returning the value unchanged, with one exception:
### Normalizations

A field that is normalized by the service **must** be annotated with the
`google.api.field_info` extension. See [AIP-202](aip-202) for guidance on using
`google.api.field_info` extension. See ([AIP-202][]) for guidance on using
this extension The allowed set of normalizations includes the following formats:

* uuid
Expand All @@ -89,15 +89,15 @@ annotation.
## Rationale

Server-modified and default values often make it harder to implement
[state-driven clients](state-driven-clients). These clients are often unable to
[declarative clients][]. These clients are often unable to
tell when their desired state matches the current state for these fields, as the
rules by which a server may modify and return values are complex, not public,
and not repeatable.

### Rationale for Single Owner Fields

When fields do not have a single owner they can cause issues for
[state-driven clients](state-driven-clients). These clients may attempt to set
[declarative clients][]. These clients may attempt to set
values for fields that are overwritten by server set values, leading to the
client entering an infinite loop to correct the change.

Expand Down Expand Up @@ -140,10 +140,9 @@ service to validate it was set correctly.

- **2023-10-31:** Update to approved.

[Declarative clients]: ./0009#declarative-clients
[aip-202]: ./202.md
[Declarative clients]: ./0009.md#declarative-clients
[aip-202]: ./0202.md

<!-- prettier-ignore-start -->
[aip-180]: ./0180.md
[state-driven-clients]: ./009.md#state-driven-clients
<!-- prettier-ignore-end -->
3 changes: 2 additions & 1 deletion aip/general/0133.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ operation (AIP-151) instead:
rpc CreateBook(CreateBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*}/books"
body: "book"
};
option (google.longrunning.operation_info) = {
response_type: "Book"
Expand Down Expand Up @@ -211,7 +212,7 @@ name and use it in references from other resources.
[data plane]: ./0111.md#data-plane
[management plane]: ./0111.md#management-plane
[errors]: ./0193.md
[field_behavior]: ./203.md
[field_behavior]: ./0203.md
[Declarative clients]: ./0009.md#declarative-clients
[permission-denied]: ./0193.md#permission-denied
[strong consistency]: ./0121.md#strong-consistency
Expand Down
Loading

0 comments on commit 29ac99c

Please sign in to comment.