AEP-0164 Linter Rules
Undelete methods- HTTP body
Undelete methods: HTTP body
Section titled “Undelete methods: HTTP body”This rule enforces that all Undelete RPCs use * as the HTTP body, as mandated in
AEP-164.
Details
Section titled “Details”This rule looks at any message beginning with Undelete, and complains
if the HTTP body field is anything other than *.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" // body: "*" should be set. };}Correct code for this rule:
// Correct.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the method. Remember to also include an aep.dev/not-precedent comment explaining why.
// (-- api-linter: core::0164::http-body=disabled// aep.dev/not-precedent: We need to do this because reasons. --)rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" };}If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- POST HTTP verb
Undelete methods: POST HTTP verb
Section titled “Undelete methods: POST HTTP verb”This rule enforces that all Undelete RPCs use the POST HTTP verb, as
mandated in AEP-164.
Details
Section titled “Details”This rule looks at any message beginning with Undelete, and complains
if the HTTP verb is anything other than POST. It does check additional
bindings if they are present.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { get: "/v1/{name=publishers/*/books/*}:undelete" // Should be `post:`. };}Correct code for this rule:
// Correct.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the method. Remember to also include an aep.dev/not-precedent comment explaining why.
// (-- api-linter: core::0164::http-method=disabled// aep.dev/not-precedent: We need to do this because reasons. --)rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { get: "/v1/{name=publishers/*/books/*}:undelete" };}If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- URI suffix
Undelete methods: URI suffix
Section titled “Undelete methods: URI suffix”This rule enforces that Undelete methods include the :undelete suffix
in the REST URI, as mandated in AEP-164.
Details
Section titled “Details”This rule looks at any method whose name starts with Undelete, and
complains if the HTTP URI does not end with :undelete.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:restore" // Should end with `:undelete`. body: "*" };}Correct code for this rule:
// Correct.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the method. Remember to also include an aep.dev/not-precedent comment explaining why.
// (-- api-linter: core::0164::http-uri-suffix=disabled// aep.dev/not-precedent: We need to do this because reasons. --)rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:restore" // Should end with `:undelete`. body: "*" };}If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- Request message
Undelete methods: Request message
Section titled “Undelete methods: Request message”This rule enforces that all Undelete RPCs have a request message name of
Undelete*Request, as mandated in AEP-164.
Details
Section titled “Details”This rule looks at any message beginning with Undelete, and complains
if the name of the corresponding input message does not match the name of the
RPC with the suffix Request appended.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.// Should be `UndeleteBookRequest`.rpc UndeleteBook(Book) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Correct code for this rule:
// Correct.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the method. Remember to also include an aep.dev/not-precedent comment explaining why.
// (-- api-linter: core::0164::request-message-name=disabled// aep.dev/not-precedent: We need to do this because reasons. --)rpc UndeleteBook(Book) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- Field behavior
Undelete methods: Field behavior
Section titled “Undelete methods: Field behavior”This rule enforces that all Undelete methods have
aep.api.field_behavior set to FIELD_BEHAVIOR_REQUIRED on their string name field, as
mandated in AEP-164.
Details
Section titled “Details”This rule looks at any message matching Undelete*Request and complains if the
name field does not have a aep.api.field_behavior annotation with a
value of FIELD_BEHAVIOR_REQUIRED.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.message UndeleteBookRequest { // The `aep.api.field_behavior` annotation should also be included. string name = 1 [(aep.api.field_info).resource_reference = { type: "library.googleapis.com/Book" }];}Correct code for this rule:
// Correct.message UndeleteBookRequest { string name = 1 [ (aep.api.field_behavior) = FIELD_BEHAVIOR_REQUIRED, (aep.api.field_info).resource_reference.type = "library.googleapis.com/Book" ];}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the field. Remember to also include an aep.dev/not-precedent comment explaining why.
message UndeleteBookRequest { // (-- api-linter: core::0164::request-name-behavior=disabled // aep.dev/not-precedent: We need to do this because reasons. --) string name = 1 [(aep.api.field_info).resource_reference = { type: "library.googleapis.com/Book" }];}If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- Name field
Undelete methods: Name field
Section titled “Undelete methods: Name field”This rule enforces that all Undelete methods have a string name
field in the request message, as mandated in AEP-164.
Details
Section titled “Details”This rule looks at any message matching Undelete*Request and complains if
either the name field is missing, or if it has any type other than string.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.message UndeleteBookRequest { string book = 1; // Field name should be `name`.}// Incorrect.message UndeleteBookRequest { bytes name = 1; // Field type should be `string`.}Correct code for this rule:
// Correct.message UndeleteBookRequest { string name = 1 [ (aep.api.field_behavior) = FIELD_BEHAVIOR_REQUIRED, (aep.api.field_info).resource_reference.type = "library.googleapis.com/Book" ];}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the message (if
the name field is missing) or above the field (if it is the wrong type).
Remember to also include an aep.dev/not-precedent comment explaining why.
// (-- api-linter: core::0164::request-name-field=disabled// aep.dev/not-precedent: We need to do this because reasons. --)message UndeleteBookRequest { string book = 1;}If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- Resource reference
Undelete methods: Resource reference
Section titled “Undelete methods: Resource reference”This rule enforces that all Undelete methods have
(aep.api.field_info).resource_reference on their string name field, as mandated in
AEP-164.
Details
Section titled “Details”This rule looks at the name field of any message matching Undelete*Request
and complains if it does not have a (aep.api.field_info).resource_reference annotation.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.message UndeleteBookRequest { // The `(aep.api.field_info).resource_reference` annotation should also be included. string name = 1 [(aep.api.field_info).field_behavior = FIELD_BEHAVIOR_REQUIRED];}Correct code for this rule:
// Correct.message UndeleteBookRequest { string name = 1 [ (aep.api.field_behavior) = FIELD_BEHAVIOR_REQUIRED, (aep.api.field_info).resource_reference.type = "library.googleapis.com/Book" ];}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the field. Remember to also include an aep.dev/not-precedent comment explaining why.
message UndeleteBookRequest { // (-- api-linter: core::0164::request-name-reference=disabled // aep.dev/not-precedent: We need to do this because reasons. --) string name = 1 [(aep.api.field_info).field_behavior = FIELD_BEHAVIOR_REQUIRED];}If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- Unknown fields
Undelete methods: Unknown fields
Section titled “Undelete methods: Unknown fields”This rule enforces that all Undelete requests do not have unexpected
fields, as mandated in AEP-164.
Details
Section titled “Details”This rule looks at any message matching Undelete*Request and complains if it
comes across any fields other than:
string name(AEP-164)string etag(AEP-154)string request_id(AEP-155)bool validate_only(AEP-163)
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.message UndeleteBookRequest { string name = 1 [ (aep.api.field_behavior) = FIELD_BEHAVIOR_REQUIRED, (aep.api.field_info).resource_reference.type = "library.googleapis.com/Book", ]; string library_id = 2; // Non-standard field.}Correct code for this rule:
// Correct.message UndeleteBookRequest { string name = 1 [ (aep.api.field_behavior) = FIELD_BEHAVIOR_REQUIRED, (aep.api.field_info).resource_reference.type = "library.googleapis.com/Book", ];}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the field. Remember to also include an aep.dev/not-precedent comment explaining why.
message UndeleteBookRequest { string name = 1 [ (aep.api.field_behavior) = FIELD_BEHAVIOR_REQUIRED, (aep.api.field_info).resource_reference.type = "library.googleapis.com/Book", ];
// (-- api-linter: core::0164::request-unknown-fields=disabled // aep.dev/not-precedent: We really need this field because reasons. --) string library_id = 2;}If you need to violate this rule for an entire file, place the comment at the top of the file.
Resources supporting soft delete- expire_time field required
Resources supporting soft delete: expire_time field required
Section titled “Resources supporting soft delete: expire_time field required”This rule enforces that all resources supporting soft delete have an
google.protobuf.Timestamp expire_time field, as mandated in AEP-164.
Details
Section titled “Details”This rule looks at any resource with a corresponding Undelete* method, and
complains if it does not have a google.protobuf.Timestamp expire_time field.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.service Library { rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" }; }}
message Book { option (google.api.resource) = { type: "library.googleapis.com/Book" pattern: "publishers/{publisher}/books/{book}" };
string name = 1;
// Should have an `expire_time` field.}Correct code for this rule:
// Correct.service Library { rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" }; };}
message Book { option (google.api.resource) = { type: "library.googleapis.com/Book" pattern: "publishers/{publisher}/books/{book}" };
string name = 1;
google.protobuf.Timestamp expire_time = 2;}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the resource. Remember to also include an aep.dev/not-precedent comment explaining why.
service Library { rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" }; };}
// (-- api-linter: core::0164::resource-expire-time-field=disabled// aep.dev/not-precedent: We need to do this because reasons. --)message Book { option (google.api.resource) = { type: "library.googleapis.com/Book" pattern: "publishers/{publisher}/books/{book}" };
string name = 1;}If you need to violate this rule for an entire file, place the comment at the top of the file.
Long-running Undelete
Long-running Undelete
Section titled “Long-running Undelete”This rule enforces that declarative-friendly undelete methods use long-running operations, as mandated in AEP-164.
Details
Section titled “Details”This rule looks at any Undelete method connected to a resource with a
google.api.resource annotation that includes style: DECLARATIVE_FRIENDLY,
and complains if it does not use long-running operations.
Examples
Section titled “Examples”Incorrect code for this rule:
// Incorrect.// Assuming that Book is styled declarative-friendly, UndeleteBook should// return a long-running operation.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Correct code for this rule:
// Correct.// Assuming that Book is styled declarative-friendly...rpc UndeleteBook(UndeleteBookRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" }; option (google.longrunning.operation_info) = { response_type: "Book" metadata_type: "OperationMetadata" };}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the message. Remember to also include an aep.dev/not-precedent comment explaining why.
// (-- api-linter: core::0164::response-lro=disabled// aep.dev/not-precedent: We need to do this because reasons. --)rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Note: Violations of declarative-friendly rules should be rare, as tools are likely to expect strong consistency.
If you need to violate this rule for an entire file, place the comment at the top of the file.
Undelete methods- Response message
Undelete methods: Response message
Section titled “Undelete methods: Response message”This rule enforces that all Undelete RPCs have a response message of
the resource, as mandated in AEP-164.
Details
Section titled “Details”This rule looks at any message beginning with Undelete, and complains
if the name of the corresponding output message does not match the name of the
RPC with the prefix Undelete removed.
It also permits a response of google.longrunning.Operation; in this case, it
checks the response_type in the google.longrunning.operation_info
annotation and ensures that it corresponds to the name of the RPC with the
prefix Undelete removed.
Examples
Section titled “Examples”Standard
Section titled “Standard”Incorrect code for this rule:
// Incorrect.// Should be `Book`.rpc UndeleteBook(UndeleteBookRequest) returns (UndeleteBookResponse) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Correct code for this rule:
// Correct.rpc UndeleteBook(UndeleteBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}Long-running operation
Section titled “Long-running operation”Incorrect code for this rule:
// Incorrect.rpc UndeleteBook(UndeleteBookRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" }; option (google.longrunning.operation_info) = { // Should be "Book". response_type: "UndeleteBookResponse" metadata_type: "UndeleteBookMetadata" };}Correct code for this rule:
// Correct.rpc UndeleteBook(UndeleteBookRequest) returns (google.longrunning.Operation) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" }; option (google.longrunning.operation_info) = { response_type: "Book" metadata_type: "UndeleteBookMetadata" };}Disabling
Section titled “Disabling”If you need to violate this rule, use a leading comment above the method. Remember to also include an aep.dev/not-precedent comment explaining why.
// (-- api-linter: core::0164::response-message-name=disabled// aep.dev/not-precedent: We need to do this because reasons. --)rpc UndeleteBook(UndeleteBookRequest) returns (UndeleteBookResponse) { option (google.api.http) = { post: "/v1/{name=publishers/*/books/*}:undelete" body: "*" };}If you need to violate this rule for an entire file, place the comment at the top of the file.