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

feat(AIP-203): introduce IDENTIFIER field behavior #1201

Merged
merged 7 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions aip/client-libraries/4231.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ message Topic {
pattern: "projects/{project}/topics/{topic}"
};

// The resource's name.
string name = 1;

// And so on...
// name and so on...
}
```

Expand Down Expand Up @@ -91,10 +88,7 @@ message LogEntry {
pattern: "billingAccounts/{billing_account}/logs/{log}"
};

// The resource's name.
string name = 1;

// And so on...
// name and so on...
}
```

Expand Down Expand Up @@ -195,10 +189,7 @@ message FeedItemTarget {
pattern: "customers/{customer}/feedItemTargets/{feed}~{feed_item}"
};

// The resource name of this event.
string name = 1;

// Other fields...
// name and other fields...
}
```

Expand Down
2 changes: 1 addition & 1 deletion aip/cloud/2510.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ message Book {
};

// The resource name of the Book.
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// A reference to another resource, a Shelf.
string shelf = 2 [(google.api.resource_reference) = {
Expand Down
6 changes: 3 additions & 3 deletions aip/general/0122.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ message Book {

// The resource name of the book.
// Format: publishers/{publisher}/books/{book}
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// Other fields...
}
Expand Down Expand Up @@ -282,7 +282,7 @@ When a field represents another resource, the field **should** be of type
`string` and accept the resource name of the other resource. The field name
**should** be equivalent to the corresponding message's name in snake case.

The field **should not** be of type `message` using the `message` that
The field **should not** be of type `message` using the `message` that
implements the resource, _unless_ the API is internal-only, has tight lifecycle
relationships, and has a permission model that enables inherited access to
embedded resources.
Expand All @@ -307,7 +307,7 @@ message Book {

// Name of the book.
// Format is `publishers/{publisher}/books/{book}`
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The shelf where the book currently sits.
// Format is `shelves/{shelf}`.
Expand Down
5 changes: 1 addition & 4 deletions aip/general/0123.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,7 @@ message Topic {
plural: "topics"
};

// The resource name of the topic.
string name = 1;

// Other fields...
// Name and other fields...
}
```

Expand Down
6 changes: 3 additions & 3 deletions aip/general/0124.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ message Book {
};

// The resource name for the book.
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The resource name for the book's author.
string author = 2 [(google.api.resource_reference) = {
Expand Down Expand Up @@ -71,7 +71,7 @@ message Book {
pattern: "publishers/{publisher}/books/{book}"
};

string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The resource names for the book's authors.
repeated string authors = 2 [(google.api.resource_reference) = {
Expand All @@ -97,7 +97,7 @@ message BookAuthor {
};

// The resource name for the book-author association.
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The resource name for the author.
string author = 2 [(google.api.resource_reference) = {
Expand Down
3 changes: 1 addition & 2 deletions aip/general/0128.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ message Book {
style: DECLARATIVE_FRIENDLY
};

string name = 1;
// Other fields...
// Name and other fields...
}
```

Expand Down
7 changes: 6 additions & 1 deletion aip/general/0134.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,14 @@ In this situation, the resource **should** contain a `string etag` field:

```proto
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "publishers/{publisher}/books/{book}"
};

// The resource name of the book.
// Format: publishers/{publisher}/books/{book}
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The title of the book.
// Example: "Mary Poppins"
Expand Down
8 changes: 7 additions & 1 deletion aip/general/0144.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ Resources **may** use repeated fields where appropriate.

```proto
message Book {
string name = 1;
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "publishers/{publisher}/books/{book}"
};

string name = 1 [(google.api.field_behavior) = IDENTIFIER];

repeated string authors = 2;
}
```
Expand Down
4 changes: 2 additions & 2 deletions aip/general/0147.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ resource implies storage of the sensitive data. For example:

```proto
message SelfManagedKeypair {
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The public key data in PEM-encoded form.
bytes public_key = 2;
Expand All @@ -42,7 +42,7 @@ indicate whether or not the sensitive information is present. For example:

```proto
message Integration {
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
string uri = 2;

// A secret to be passed in the `Authorization` header of the webhook.
Expand Down
7 changes: 6 additions & 1 deletion aip/general/0149.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ its default value (`0`, `false`, or empty string) from not setting it at all:
```proto
// A representation of a book in a library.
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "publishers/{publisher}/books/{book}"
};

// The name of the book.
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The rating for the book, from 0 to 5.
// 0 is distinct from no rating.
Expand Down
13 changes: 5 additions & 8 deletions aip/general/0152.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ distinct setup, configuration, and execution:

```proto
message WriteBookJob {
// The resource name for the writing job.
string name = 1 [(google.api.resource) = {
option (google.api.resource) = {
type: "library.googleapis.com/WriteBookJob"
pattern: "publishers/{publisher}/writeBookJobs/{write_book_job}"
}];
};

// Additional configuration...
// Name and other fields...
}
```

Expand Down Expand Up @@ -116,10 +115,8 @@ message WriteBookJobExecution {
pattern: "publishers/{publisher}/writeBookJobs/{write_book_job}/executions/{execution}"
};

string name = 1;

// Other information about the execution, such as metadata, the result,
// error information, etc.
// Name and other information about the execution, such as metadata, the
// result, error information, etc.
}
```

Expand Down
4 changes: 2 additions & 2 deletions aip/general/0156.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ message Config {
pattern: "users/{user}/config"
};

string name = 1;
// additional fields including name
}
```

Expand Down Expand Up @@ -66,7 +66,7 @@ rpc UpdateConfig(UpdateConfigRequest) returns (Config) {
method if all fields on the resource are [output only][aip-203].
- Singleton resources **may** define the [`List`][aip-132] method, but **must**
implement it according to [AIP-159][aip-159]. See the example below.
- The trailing segment in the path pattern that typically represents the
- The trailing segment in the path pattern that typically represents the
collection **should** be the `plural` form of the Singleton resource e.g.
`/v1/{parent=users/*}/configs`.
- If a parent resource ID is provided instead of the hyphen `-` as per
Expand Down
7 changes: 6 additions & 1 deletion aip/general/0161.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,14 @@ map to indicate the specification of particular sub-fields in the collection:

```proto
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "publishers/{publisher}/books/{book}"
};

// The name of the book.
// Format: publishers/{publisher}/books/{book}
string name = 1;
string name = 1 [(google.api.field_behavior) = IDENTIFIER];

// The author or authors of the book.
// Valid field masks: authors, authors.*.given_name, authors.*.family_name
Expand Down
5 changes: 1 addition & 4 deletions aip/general/0162.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ APIs implementing resources with a revision history **must** provide a

```proto
message Book {
// The name of the book.
string name = 1;

// Other fields…
// Name and other fields…

// The revision ID of the book.
// A new revision is committed whenever the book is changed in any way.
Expand Down
9 changes: 5 additions & 4 deletions aip/general/0180.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ For example:

```proto
message Book {
string name = 1;
// google.api.resource and other annotations and fields

// The genre of the book
// If this is not set when the book is created, the field will be given a value of FICTION.
enum Genre {
Expand All @@ -176,7 +177,8 @@ Changing to:

```proto
message Book {
string name = 1;
// google.api.resource and other annotations and fields

// The genre of the book
// If this is not set when the book is created, the field will be given a value of NONFICTION.
enum Genre {
Expand All @@ -203,8 +205,7 @@ Consider the following proto, where the default value of `wheels` is `2`:
```proto
// A representation of an automobile
message Automobile {
// The name of the automobile.
string name = 1;
// google.api.resource and other annotations and fields

// The number of wheels on the automobile.
// The default value is 2, when no value is sent by the client.
Expand Down
24 changes: 20 additions & 4 deletions aip/general/0203.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ document this behavior for clients.

## Vocabulary

### Identifier

The use of `IDENTIFIER` indicates that a field within a resource message is used
to identify the resource. It **must** be attached to the `name` field and **must
not** be attached to any other field (see [fields representing resource names]).

This annotation **must not** be applied to references to other resources within
a message.

### Immutable

The use of `IMMUTABLE` indicates that a field on a resource cannot be changed
Expand All @@ -57,7 +66,8 @@ requested.

Potential use cases for immutable fields (this is not an exhaustive list) are:

- Names or IDs which are set on creation and then used as a primary key.
- Attributes of resources that are not modifiable for the lifetime of the
application (e.g. a disk type).

**Note:** Fields which are "conditionally immutable" **must not** be given the
immutable annotation.
Expand Down Expand Up @@ -169,17 +179,21 @@ following are examples of backwards incompatible changes with
`google.api.field_behavior`:

* Adding `REQUIRED` to an existing field previously considered `OPTIONAL`
(implicitly or otherwise).
* Adding a new field annotated as `REQUIRED` to an existing request message.
(implicitly or otherwise)
* Adding a new field annotated as `REQUIRED` to an existing request message
* Adding `OUTPUT_ONLY` to an existing field previously accepted as input
* Removing `OUTPUT_ONLY` from an existing field previously ignored as input
* Adding `INPUT_ONLY` to an existing field previously emitted as output
* Adding `IMMUTABLE` to an existing field previously considered mutable
* Removing `OUTPUT_ONLY` from an existing field previously ignored as input
* Removing `IDENTIFIER` from an existing field.

There are some changes that *are* backwards compatible, which are as follows:

* Adding `OPTIONAL` to an existing field
* Adding `IDENTIFIER` to an existing `name` field
* Changing from `REQUIRED` to `OPTIONAL` on an existing field
* Changing from `OUTPUT_ONLY` and/or `IMMUTABLE` to `IDENTIFIER` on an existing
field
* Removing `REQUIRED` from an existing field
* Removing `INPUT_ONLY` from an existing field previously excluded in responses
* Removing `IMMUTABLE` from an existing field previously considered immutable
Expand Down Expand Up @@ -228,9 +242,11 @@ surpass the costs to clients and API users of not doing so.
[aip-180]: ./0180.md
[google.api.FieldBehavior]: https://github.com/googleapis/googleapis/blob/master/google/api/field_behavior.proto#L49
[Declarative client]: ./0009.md#declarative-clients
[fields representing resource names]: ./0122.md#fields-representing-resource-names

## Changelog

- **2023-08-25**: Add guidance on `IDENTIFIER`.
- **2023-07-20**: Describe compatibility guidance with new section.
- **2023-05-24**: Clarify that `IMMUTABLE` does not imply input nor required.
- **2023-05-10**: Added guidance to require the annotation.
Expand Down
3 changes: 1 addition & 2 deletions aip/general/0214.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ library.

```proto
message ExpiringResource {
// The name of the resource; the format is: ...
string name = 1;
// google.api.resource and other annotations and fields

oneof expiration {
// Timestamp in UTC of when this resource is considered expired.
Expand Down
Loading