Skip to content

Commit

Permalink
AIP-4234: Common Service Client Mix-ins (#694)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahdietz committed Aug 20, 2021
1 parent f9376f5 commit 4971fdc
Showing 1 changed file with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions aip/client-libraries/4234.md
@@ -0,0 +1,135 @@
---
id: 4234
state: reviewing
created: 2021-06-07
---

# 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:

```json
{
"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:

```proto
service LibraryService {
rpc ListBooks(ListBookRequest) 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.

[apis]: https://github.com/googleapis/googleapis/blob/master/google/api/service.proto#L96
[google.api.Service]: https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
[google.api.Http]: https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
[http]: https://github.com/googleapis/googleapis/blob/master/google/api/service.proto#L124
[LocationsClient]: https://pkg.go.dev/google.golang.org/genproto@v0.0.0-20210325141258-5636347f2b14/googleapis/cloud/location#LocationsClient

0 comments on commit 4971fdc

Please sign in to comment.