Skip to content

AEP-0151 Linter Rules

LRO- Reachable metadata types

LRO: Reachable metadata types

This rule enforces that methods returning long-running operations define their metadata messages in the same file or a directly-imported file, as mandated in AEP-151.

Details

This rule looks at any method with a return type of google.longrunning.Operation, and complains if the message designated by the metadata_type field are not defined in the same file, or a file directly imported by the file.

Because these message names are strings, and a string reference does not require an import statement, defining the metadata types elsewhere can cause problems for tooling. To prevent this, and also to maintain consistency with the file layout in AEP-191, the linter complains if the message is not defined in the same file or a file directly imported by the file.

Examples

Incorrect code for this rule:

In library_service.proto:

// Incorrect.
service Library {
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}
}

In operations.proto:

// Incorrect.
message WriteBookResponse {
// Should be in the same file or directly imported.
}
message WriteBookMetadata {
// Should be in the same file or directly imported.
}

Correct code for this rule:

Same file:

// Correct.
service Library {
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}
}
// Later in the file...
message WriteBookResponse {
// ...
}
message WriteBookMetadata {
// ...
}

Separate files:

In library_service.proto:

// Correct.
import "operations.proto";
service Library {
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}
}

In operations.proto:

// Correct.
message WriteBookResponse {
// ...
}
message WriteBookMetadata {
// ...
}

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::0151::lro-metadata-reachable=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "UndefinedMetadataMessage"
};
}

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

LRO metadata type

LRO metadata type

This rule enforces that methods returning long-running operations specify a metadata type in the google.longrunning.operation_info annotation, as mandated in AEP-151.

Details

This rule looks at any method with a return type of google.longrunning.Operation, and complains if the metadata_type field google.longrunning.operation_info annotation is not present.

Additionally, it complains if the metadata type is set to google.protobuf.Empty, and recommends making an blank message instead, to permit future extensibility.

Examples

Incorrect code for this rule:

// Incorrect.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
// `metadata_type` is not provided.
};
}
// Incorrect.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "google.protobuf.Empty" // Should not be `Empty`.
};
}

Correct code for this rule:

// Correct.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}

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::0151::lro-metadata-type=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "google.protobuf.Empty"
};
}

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

LRO- Reachable response types

LRO: Reachable response types

This rule enforces that methods returning long-running operations define their response messages in the same file or a directly-imported file, as mandated in AEP-151.

Details

This rule looks at any method with a return type of google.longrunning.Operation, and complains if the message designated by the response_type field are not defined in the same file, or a file directly imported by the file.

Because these message names are strings, and a string reference does not require an import statement, defining the response types elsewhere can cause problems for tooling. To prevent this, and also to maintain consistency with the file layout in AEP-191, the linter complains if the message is not defined in the same file or a file directly imported by the file.

Examples

Incorrect code for this rule:

In library_service.proto:

// Incorrect.
service Library {
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}
}

In operations.proto:

// Incorrect.
message WriteBookResponse {
// Should be in the same file or directly imported.
}
message WriteBookMetadata {
// Should be in the same file or directly imported.
}

Correct code for this rule:

Same file:

// Correct.
service Library {
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}
}
// Later in the file...
message WriteBookResponse {
// ...
}
message WriteBookMetadata {
// ...
}

Separate files:

In library_service.proto:

// Correct.
import "operations.proto";
service Library {
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}
}

In operations.proto:

// Correct.
message WriteBookResponse {
// ...
}
message WriteBookMetadata {
// ...
}

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::0151::lro-response-reachable=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "google.protobuf.Empty"
metadata_type: "WriteBookMetadata"
};
}

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

LRO response type

LRO response type

This rule enforces that methods returning long-running operations specify a response type in the google.longrunning.operation_info annotation, as mandated in AEP-151.

Details

This rule looks at any method with a return type of google.longrunning.Operation, and complains if the response_type field google.longrunning.operation_info annotation is not present.

Additionally, it complains if the response type is set to google.protobuf.Empty, and recommends making an blank message instead, to permit future extensibility. However, methods with names beginning with Delete are exempt from this check (see AEP-135).

Examples

Incorrect code for this rule:

// Incorrect.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
// `response_type` is not provided.
metadata_type: "WriteBookMetadata"
};
}
// Incorrect.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "google.protobuf.Empty" // Should not use `Empty`.
metadata_type: "WriteBookMetadata"
};
}

Correct code for this rule:

// Correct.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}

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::0151::lro-response-type=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "google.protobuf.Empty"
metadata_type: "WriteBookMetadata"
};
}

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

Long-running operation info

Long-running operation info

This rule enforces that methods returning long-running operations include an annotation specifying their response type and metadata type, as mandated in AEP-151.

Details

This rule looks at any method with a return type of google.longrunning.Operation, and complains if the google.longrunning.operation_info annotation is not present.

Examples

Incorrect code for this rule:

// Incorrect.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
// There should be a google.longrunning.operation_info annotation.
}

Correct code for this rule:

// Correct.
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "WriteBookResponse"
metadata_type: "WriteBookMetadata"
};
}

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::0151::operation-info=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc WriteBook(WriteBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{path=publishers/*/books}:write"
body: "*"
};
}

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

Paginated methods- Unary responses

Paginated methods: Unary responses

This rule enforces that all long-running operation methods use unary responses, as mandated in AEP-151.

Details

This rule looks at any message returning a google.longrunning.Operation, and complains if the method uses gRPC server streaming (the stream keyword).

Examples

Incorrect code for this rule:

// Incorrect.
// Streaming is prohibited on long-running operations.
rpc ReadBook(ReadBookRequest) returns (stream google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*/books/*}:read"
body: "*"
};
}

Correct code for this rule:

// Correct.
rpc ReadBook(ReadBookRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*/books/*}:read"
body: "*"
};
}

Disabling

If you need to violate this rule, use a leading comment above the message or above the field. Remember to also include an aep.dev/not-precedent comment explaining why.

// (-- api-linter: core::0151::response-unary
// aep.dev/not-precedent: We need to do this because reasons. --)
rpc ReadBook(ReadBookRequest) returns (stream google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*/books/*}:read"
body: "*"
};
}

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