Skip to content

AEP-0164 Linter Rules

Undelete methods- HTTP body

Undelete methods: HTTP body

This rule enforces that all Undelete RPCs use * as the HTTP body, as mandated in AEP-164.

Details

This rule looks at any message beginning with Undelete, and complains if the HTTP body field is anything other than *.

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

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

This rule enforces that all Undelete RPCs use the POST HTTP verb, as mandated in AEP-164.

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

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

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

This rule enforces that Undelete methods include the :undelete suffix in the REST URI, as mandated in AEP-164.

Details

This rule looks at any method whose name starts with Undelete, and complains if the HTTP URI does not end with :undelete.

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

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

This rule enforces that all Undelete RPCs have a request message name of Undelete*Request, as mandated in AEP-164.

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

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

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

This rule enforces that all Undelete methods have google.api.field_behavior set to REQUIRED on their string name field, as mandated in AEP-164.

Details

This rule looks at any message matching Undelete*Request and complains if the name field does not have a google.api.field_behavior annotation with a value of REQUIRED.

Examples

Incorrect code for this rule:

// Incorrect.
message UndeleteBookRequest {
// The `google.api.field_behavior` annotation should also be included.
string name = 1 [(google.api.resource_reference) = {
type: "library.googleapis.com/Book"
}];
}

Correct code for this rule:

// Correct.
message UndeleteBookRequest {
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference).type = "library.googleapis.com/Book"
];
}

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 [(google.api.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

This rule enforces that all Undelete methods have a string name field in the request message, as mandated in AEP-164.

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

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 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference).type = "library.googleapis.com/Book"
];
}

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

This rule enforces that all Undelete methods have google.api.resource_reference on their string name field, as mandated in AEP-164.

Details

This rule looks at the name field of any message matching Undelete*Request and complains if it does not have a google.api.resource_reference annotation.

Examples

Incorrect code for this rule:

// Incorrect.
message UndeleteBookRequest {
// The `google.api.resource_reference` annotation should also be included.
string name = 1 [(google.api.field_behavior) = REQUIRED];
}

Correct code for this rule:

// Correct.
message UndeleteBookRequest {
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference).type = "library.googleapis.com/Book"
];
}

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 [(google.api.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

This rule enforces that all Undelete requests do not have unexpected fields, as mandated in AEP-164.

Details

This rule looks at any message matching Undelete*Request and complains if it comes across any fields other than:

Examples

Incorrect code for this rule:

// Incorrect.
message UndeleteBookRequest {
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.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 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference).type = "library.googleapis.com/Book",
];
}

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 [
(google.api.field_behavior) = REQUIRED,
(google.api.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

This rule enforces that all resources supporting soft delete have an google.protobuf.Timestamp expire_time field, as mandated in AEP-164.

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

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

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

This rule enforces that declarative-friendly undelete methods use long-running operations, as mandated in AEP-164.

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

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

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

This rule enforces that all Undelete RPCs have a response message of the resource, as mandated in AEP-164.

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

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

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

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.