Skip to content

AEP-0121 Linter Rules

Resources must not form a resource reference cycle

Resources must not form a resource reference cycle

This rule enforces that resources do not create reference cycles of mutable references as mandated in AEP-121.

Details

This rule scans the fields of every resource and ensures that any references to other resources do not create a mutable cycle between them.

Examples

Incorrect code for this rule:

message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
string name = 1;
// Incorrect. Creates potential reference cycle.
string author = 2 [
(google.api.resource_reference).type = "library.googleapis.com/Author"
];
}
message Author {
option (google.api.resource) = {
type: "library.googleapis.com/Author"
pattern: "authors/{author}"
};
string name = 1;
// Incorrect. Creates potential reference cycle.
string book = 2 [
(google.api.resource_reference).type = "library.googleapis.com/Book"
];
}

Correct code for this rule:

message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
string name = 1;
// Correct because the other reference is OUTPUT_ONLY.
string author = 2 [
(google.api.resource_reference).type = "library.googleapis.com/Author"
];
}
message Author {
option (google.api.resource) = {
type: "library.googleapis.com/Author"
pattern: "authors/{author}"
};
string name = 1;
// Correct because an OUTPUT_ONLY reference breaks the mutation cycle.
string book = 2 [
(google.api.resource_reference).type = "library.googleapis.com/Book",
(google.api.field_behavior) = OUTPUT_ONLY
];
}

Disabling

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

message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
string name = 1;
// (-- api-linter: core::0121::no-mutable-cycles=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
string author = 2 [
(google.api.resource_reference).type = "library.googleapis.com/Author"
];
}
message Author {
option (google.api.resource) = {
type: "library.googleapis.com/Author"
pattern: "authors/{author}"
};
string name = 1;
// (-- api-linter: core::0121::no-mutable-cycles=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
string book = 2 [
(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.

Resource must support get

Resource must support get

This rule enforces that all resources support the Get operation as mandated in AEP-121.

Details

This rule scans a service for Create, Update, and List methods for resources, and ensures each one has a Get method.

Examples

Incorrect code for this rule:

// Incorrect.
service Foo {
// Book has a create, but no Get method.
rpc CreateBook(CreateBookRequest) returns (Book) {};
}
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
}

Correct code for this rule:

// Correct.
service Foo {
rpc CreateBook(CreateBookRequest) returns (Book) {};
rpc GetBook(GetBookRequest) returns (Book) {};
}
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
}

Disabling

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

// (-- api-linter: core::0121::resource-must-support-get=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
service Foo {
// Book has a create, but no Get method.
rpc CreateBook(CreateBookRequest) returns (Book) {};
}
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
}

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

Resource must support list

Resource must support list

This rule enforces that all, non-Singleton resources support the List operation as mandated in AEP-121.

Details

This rule scans a service for Create, Update, and Get methods for resources (that are not Singletons), and ensures each one has a List method.

Examples

Incorrect code for this rule:

// Incorrect.
service Foo {
// Book has a create, but no List method.
rpc CreateBook(CreateBookRequest) returns (Book) {};
}
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
}

Correct code for this rule:

// Correct.
service Foo {
rpc CreateBook(CreateBookRequest) returns (Book) {};
rpc ListBooks(ListBookRequest) returns (ListBooksResponse) {};
}
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
}

Disabling

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

// (-- api-linter: core::0121::resource-must-support-list=disabled
// aep.dev/not-precedent: We need to do this because reasons. --)
service Foo {
// Book has a create, but no List method.
rpc CreateBook(CreateBookRequest) returns (Book) {};
}
message Book {
option (google.api.resource) = {
type: "library.googleapis.com/Book"
pattern: "books/{book}"
};
}

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