Skip to content

AEP-0135 Linter Rules

Delete methods- force field

Delete methods: force field

This rule enforces that the standard Delete method for a resource that parents other resources in the service have a bool force field in the request message, as mandated in AEP-135.

Details

This rule looks at any message matching Delete*Request for a resource with child resources in the same service and complains if the force field is missing.

Examples

Incorrect code for this rule:

// Incorrect.
message DeletePublisherRequest {
// Where Publisher parents the Book resource.
string path = 1 [
(google.api.resource_reference).type = "library.googleapis.com/Publisher"];
// Missing `bool force` field.
}

Correct code for this rule:

// Correct.
message DeletePublisherRequest {
// Where Publisher parents the Book resource.
string path = 1 [
(google.api.resource_reference).type = "library.googleapis.com/Publisher"];
// If set to true, any books from this publisher will also be deleted.
// (Otherwise, the request will only work if the publisher has no books.)
bool force = 2;
}

Disabling

If you need to violate this rule, use a leading comment above the message (if the path 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::0135::force-field=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
message DeletePublisherRequest {
// Where Publisher parents the Book resource.
string path = 1 [
(google.api.resource_reference).type = "library.googleapis.com/Publisher"];
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- No HTTP body

Delete methods: No HTTP body

This rule enforces that all Delete RPCs omit the HTTP body, as mandated in AEP-135.

Details

This rule looks at any message matching beginning with Delete, and complains if the HTTP body field is set.

Examples

Incorrect code for this rule:

// Incorrect.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
body: "*" // This should be absent.
};
}

Correct code for this rule:

// Correct.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

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::0135::http-body=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
body: "*"
};
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- DELETE HTTP verb

Delete methods: DELETE HTTP verb

This rule enforces that all Delete RPCs use the DELETE HTTP verb, as mandated in AEP-135.

Details

This rule looks at any message matching beginning with Delete, and complains if the HTTP verb is anything other than DELETE. It does check additional bindings if they are present.

Examples

Incorrect code for this rule:

// Incorrect.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books/*}" // Should be `delete:`.
};
}

Correct code for this rule:

// Correct.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

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::0135::http-method=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books/*}"
};
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- HTTP URI path field

Delete methods: HTTP URI path field

This rule enforces that all Delete RPCs map the path field to the HTTP URI, as mandated in AEP-135.

Details

This rule looks at any message matching beginning with Delete, and complains if the path variable is not included in the URI. It does check additional bindings if they are present.

Examples

Incorrect code for this rule:

// Incorrect.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/publishers/*/books/*" // The `path` field should be extracted.
};
}

Correct code for this rule:

// Correct.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

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::0135::http-uri-path=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/publishers/*/books/*"
};
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- Method signature

Delete methods: Method signature

This rule enforces that all Delete standard methods have a google.api.method_signature annotation with a value of "path", as mandated in AEP-135.

Details

This rule looks at any method beginning with Delete, and complains if the google.api.method_signature annotation is missing, or if it is set to any value other than "path". Additional method signatures, if present, are ignored.

Examples

Incorrect code for this rule:

// Incorrect.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
// A google.api.method_signature annotation should be present.
}
// Incorrect.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.method_signature) = "book"; // Should be "path".
}

Correct code for this rule:

// Correct.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.method_signature) = "path";
}

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::0135::method-signature=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.method_signature) = "book";
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete requests- force field

Delete requests: force field

This rule enforces that all Delete request force fields have type bool, as mandated in AEP-135.

Details

This rule looks at any message matching Delete*Request that contains a force field and complains if the field is not a singular bool.

Examples

Incorrect code for this rule:

message DeletePublisherRequest {
string path = 1 [
(google.api.resource_reference).type = "library.googleapis.com/Publisher",
(google.api.field_behavior) = REQUIRED
];
int32 force = 2; // Field type should be `bool`.
}

Correct code for this rule:

message DeletePublisherRequest {
string path = 1 [
(google.api.resource_reference).type = "library.googleapis.com/Publisher",
(google.api.field_behavior) = REQUIRED
];
bool force = 2;
}

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 DeletePublisherRequest {
string path = 1 [
(google.api.resource_reference).type = "library.googleapis.com/Publisher",
(google.api.field_behavior) = REQUIRED
];
// (-- api-linter: core::0135::request-force-field=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
int32 force = 2;
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- Request message

Delete methods: Request message

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

Details

This rule looks at any message matching beginning with Delete, 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 `DeleteBookRequest`.
rpc DeleteBook(Book) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

Correct code for this rule:

// Correct.
rpc DeleteBook(DeleteBookRequest) returns (Book) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

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::0135::request-message-name=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc DeleteBook(Book) returns (google.protobuf.Empty) {
option (google.api.http) = {
get: "/v1/{path=publishers/*/books/*}"
};
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- Field behavior

Delete methods: Field behavior

This rule enforces that all Delete standard methods have google.api.field_behavior set to REQUIRED on their string path field, as mandated in AEP-135.

Details

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

Examples

Incorrect code for this rule:

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

Correct code for this rule:

// Correct.
message DeleteBookRequest {
string path = 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 DeleteBookRequest {
// (-- api-linter: core::0135::request-path-behavior=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
string path = 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.

Delete methods- path field

Delete methods: path field

This rule enforces that all Delete standard methods have a string path field in the request message, as mandated in AEP-135.

Details

This rule looks at any message matching Delete*Request and complains if either the path field is missing, or if it has any type other than string.

Examples

Incorrect code for this rule:

// Incorrect.
message DeleteBookRequest {
string book = 1; // Field path should be `path`.
}
// Incorrect.
message DeleteBookRequest {
bytes path = 1; // Field type should be `string`.
}

Correct code for this rule:

// Correct.
message DeleteBookRequest {
string path = 1;
}

Disabling

If you need to violate this rule, use a leading comment above the message (if the path 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::0135::request-path-field=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
message DeleteBookRequest {
string book = 1;
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- Resource reference

Delete methods: Resource reference

This rule enforces that all Delete standard methods have google.api.resource_reference on their string path field, as mandated in AEP-135.

Details

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

Examples

Incorrect code for this rule:

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

Correct code for this rule:

// Correct.
message DeleteBookRequest {
string path = 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 DeleteBookRequest {
// (-- api-linter: core::0135::request-path-reference=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
string path = 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.

Delete methods- Name field

Delete methods: Name field

This rule enforces that all Delete standard methods have a string path field in the request message, as mandated in AEP-135.

Details

This rule looks at any message matching Delete*Request and complains if the path field is missing.

Examples

Incorrect code for this rule:

// Incorrect.
message DeleteBookRequest {
// Field path should be `path`.
string book = 1;
}

Correct code for this rule:

// Correct.
message DeleteBookRequest {
string path = 1;
}

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::0135::request-path-required=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
message DeleteBookRequest {
string book = 1;
}

If you need to violate this rule for an entire file, place the comment at the top of the file.

Delete methods- Required fields

Delete methods: Required fields

This rule enforces that all Delete standard methods do not have unexpected required fields, as mandated in AEP-135.

Details

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

Examples

Incorrect code for this rule:

// Incorrect.
message DeleteBookRequest {
string path = 1 [(google.api.field_behavior) = REQUIRED];
// Non-standard required field.
bool allow_missing = 4 [(google.api.field_behavior) = REQUIRED];
}

Correct code for this rule:

// Correct.
message DeleteBookRequest {
string path = 1 [(google.api.field_behavior) = REQUIRED];
bool allow_missing = 4 [(google.api.field_behavior) = OPTIONAL];
}

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 DeleteBookRequest {
string path = 1 [(google.api.field_behavior) = REQUIRED];
// (-- api-linter: core::0135::request-required-fields=disabled
// aep.dev/not-precedent: We really need this field to be required because
// reasons. --)
bool allow_missing = 4 [(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.

Delete methods- Unknown fields

Delete methods: Unknown fields

This rule enforces that all Delete standard methods do not have unexpected fields, as mandated in AEP-135.

Details

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

Examples

Incorrect code for this rule:

// Incorrect.
message DeleteBookRequest {
string path = 1;
string library_id = 2; // Non-standard field.
}

Correct code for this rule:

// Correct.
message DeleteBookRequest {
string path = 1;
}

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 DeleteBookRequest {
string path = 1;
// (-- api-linter: core::0135::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.

Long-running Delete

Long-running Delete

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

Details

This rule looks at any Delete 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, DeleteBook should
// return a long-running operation.
rpc DeleteBook(DeleteBookRequest) returns (Book) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

Correct code for this rule:

// Correct.
// Assuming that Book is styled declarative-friendly...
rpc DeleteBook(DeleteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
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::0135::response-lro=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc DeleteBook(DeleteBookRequest) returns (Book) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

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.

Delete methods- Response message

Delete methods: Response message

This rule enforces that all Delete RPCs have a response message of google.protobuf.Empty or the resource, as mandated in AEP-135.

Details

This rule looks at any message matching beginning with Delete, and complains if the name of the corresponding output message is not one of:

  • google.protobuf.Empty
  • The name of the RPC with the prefix Delete 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 either google.protobuf.Empty or the name of the RPC with the prefix Delete removed.

Examples

Standard

Incorrect code for this rule:

// Incorrect.
// Should be `google.protobuf.Empty` or the resource.
rpc DeleteBook(DeleteBookRequest) returns (DeleteBookResponse) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

Correct code for this rule:

// Correct.
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}
// Correct.
rpc DeleteBook(DeleteBookRequest) returns (Book) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

Important: For declarative-friendly resources, only the resource is permitted as a return type (and therefore only the second example is valid).

Long-running operation

Incorrect code for this rule:

// Incorrect.
rpc DeleteBook(DeleteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
option (google.longrunning.operation_info) = {
// Should be "google.protobuf.Empty" or "Book".
response_type: "DeleteBookResponse"
metadata_type: "DeleteBookMetadata"
};
}

Correct code for this rule:

// Correct.
rpc DeleteBook(DeleteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
option (google.longrunning.operation_info) = {
response_type: "google.protobuf.Empty"
metadata_type: "DeleteBookMetadata"
};
}
// Correct.
rpc DeleteBook(DeleteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
option (google.longrunning.operation_info) = {
response_type: "Book"
metadata_type: "DeleteBookMetadata"
};
}

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::0135::response-message-name=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc DeleteBook(DeleteBookRequest) returns (DeleteBookResponse) {
option (google.api.http) = {
delete: "/v1/{path=publishers/*/books/*}"
};
}

If you need to violate this rule for an entire file, place the comment at the top of the file.