Skip to content

List methods: Unknown fields (Response) incompatible with multi-resource parents #1607

@seanlafferty-ibm

Description

@seanlafferty-ibm

https://google.aip.dev/124#multiple-many-to-one-associations explains a resource can have multiple parents, but one parent must be the canonical one. I take this to mean that if we have a resource Book canonically at /publishers/{publisher}/books/{book}, it is permissable to have a ListGenreBooks at GET /genres/{genre}/books which returns Books.

Full example in protobuf

syntax = "proto3";

package foo;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";

// My Service
service TestThing {
     // List Books
  rpc ListBooks(ListBooksRequest) returns (ListBooksResponse) {
    option (google.api.http) = {get: "/{parent=publishers/*}/books"};
    option (google.api.method_signature) = "parent";
  }
     // List Books by genre
  rpc ListGenreBooks(ListGenreBooksRequest) returns (ListGenreBooksResponse) {
    option (google.api.http) = {get: "/{parent=genre/*}/books"};
    option (google.api.method_signature) = "parent";
  }
}

// Book
message Book {
  option (google.api.resource) = {
    type: "library.googleapis.com/Book"
    pattern: "publishers/{publisher}/books/{book}"
    singular: "book"
    plural: "books"
  };
  // Name
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];
}

// List books
message ListBooksRequest {
  // Format: publishers/{publisher}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {child_type: "library.googleapis.com/Book"}
  ];
    // Page size
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];
// Page token
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// List books
message ListBooksResponse {
    //books
  repeated Book books = 1;
   // next page token
  string next_page_token = 2;
}

// List genre books
message ListGenreBooksRequest {
  // Format: genre/{genre}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {child_type: "library.googleapis.com/Book"}
  ];
    // Page size
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];
// Page token
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// List books
message ListGenreBooksResponse {
  // Books
  repeated Book books = 1;
   // next page token
  string next_page_token = 2;
}

The linter fails this with

List responses should only contain fields explicitly described in AIPs. https://linter.aip.dev/132/response-unknown-fields (buf-plugin-google-api)

on the ListGenreBooksResponse repeated Book books = 1; line. I considered maybe the field should be called genre_books, but that fails with another error

Paginated resource response field name should be the snake_case form of the resource type plural defined in the `(google.api.resource)` annotation. https://linter.aip.dev/158/response-plural-first-field (buf-plugin-google-api)

So my query is, do I understand the guidance around multi-parent resources correctly? And if so, what is the idiomatic field name for the repeated resource in ListGenreBooksResponse message? And ultimately, is the linter wrong in this case? (I tried to find an example of this in the googleapis repo, but couldn't figure out a good way to search for this situation).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions