AIP-4234

Common service client mixins

Often, APIs can have common features for administering resources that are separated into utility services. These common, utility services are shared among the discrete product services. These common services each have a centrally-defined surface, but individual instances are hosted alongside each product service. Thus, the surfaces of each common service hosted by the product service are "mixed in" at runtime.

Guidance

Client libraries may provide client methods for the common services that its API declares to be mixed-in. Such methods improve the user experience by presenting the mixin methods from a client configured to communicate with the product service that hosts the mixin service.

If client libraries support mixin services, they must support the following common services (and may support others):

  • google.cloud.location.Locations
  • google.iam.v1.IAMPolicy
  • google.longrunning.Operations

Note: The list of supported mixin services and the mixin services themselves both change infrequently. Any new common service to be supported must be added to the list here and generators must be updated.

To be generated into a client library, a mixin service must be declared under apis in a google.api.Service. Furthermore, only the RPCs with google.api.http bindings declared in the http configuration of the same google.api.Service can be generated (more details on these bindings in AIP-127). If a mixin service RPC does not have a google.api.http rule declared in the google.api.Service, it must not be generated.

Implementing mixin support

Generator configuration

Client library generators must accept the file path of a google.api.Service in YAML form. This file is specified via a flag that must be optional. In other words, the flag must not be required for basic client generation that omits the mixin methods.

Mixin API client configuration

If a mixin API utilizes client library configuration (i.e. annotations, default retry settings, etc.) such as google.api.method_signature or request header injection, generators may support it in the generated mixin methods if the configuration is accessible.

Where client library configuration calls for a fully-qualified name, the mixin's fully-qualified name must be used. That is to say, the host service must not refer to a mixin element as if it was in its own package.

For example, configuring google.iam.v1.IAMPolicy.GetIAMPolicy with default retry and timeout settings would be as follows:

{
  "name": [{ "service": "google.iam.v1.IAMPolicy", "method": "GetIAMPolicy" }],
  "timeout": "60s",
  "retryPolicy": {
    "initialBackoff": "0.1s",
    "maxBackoff": "5s",
    "backoffMultiplier": 1.3,
    "retryableStatusCodes": ["UNKNOWN"]
  }
}

Generating mixin methods

The mixin API RPCs should be generated as methods on the surface of the host API's service client library, alongside the host service's RPCs. This presents them as top-level methods on the client, but under-the-hood, the appropriate mixin API stub or request should be invoked. However, generators may choose to present the mixin API RPCs in a different manner if it is more language idiomatic.

Note: For gRPC clients, the mixin API gRPC stub must be used in order to properly construct the gRPC request. For example, the generated, Go gRPC stub LocationsClient must be used to invoke RPCs for the google.cloud.location.Locations mixin, as opposed to that of the host service's gRPC stub.

Multiple host service clients

If there are multiple services defined by the host API that would result in multiple clients being generated, generators must include the mixin methods on all eligible, generated service clients.

Overriding a duplicate RPC

Client library generators must not generate a mixin method on any host service client if a host service already defines an RPC with the same name. For example, take the following service definition:

service LibraryService {
  rpc ListBooks(ListBooksRequest) returns (ListBooksResponse);

  // Other host API RPCs...

  // Redefinitions of the google.iam.v1.IAMPolicy mixin service.
  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest)
      returns (google.iam.v1.Policy);

  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest)
      returns (google.iam.v1.Policy);

  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest)
      returns (google.iam.v1.TestIamPermissionsResponse);
}

Should the host API declare the google.iam.v1.IAMPolicy as a mixin service, client library generators must not generate the resulting mixin methods that match the names explicitly declared above for any service client in the host proto package, but they must generate the other methods for this mixin. In this case, the generator may log a warning indicating that a collision was avoided, or silently skip the mixin methods in question.