-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Customizing constructors
A client may need to be instantiated with API-specific configuration or have some API-specific behavior.
To support customizing client construction, client libraries support the implementation of an internal client constructor hook. This hook enables integration of API-specific configuration or behaviors directly into the client library constructor.
Given the following protobuf service:
service LibraryService {
...
}The LibraryClient has the following service-specific clientHook:
var newLibraryClientHook clientHookA clientHook implementation that detects the presence of an emulator host
name in the environment might be as follows:
package library
import (
"context"
"os"
"google.golang.org/api/option"
"google.golang.org/grpc"
)
func init() {
newLibraryClientHook = func(ctx context.Context, p clientHookParams) ([]option.ClientOption, error) {
if emulator := os.Getenv("LIBRARY_EMULATOR_HOST"); emulator != "" {
return []option.ClientOption{
option.WithEndpoint(emulator),
option.WithGRPCDialOption(grpc.WithInsecure())
}, nil
}
return nil, nil
}
}Each client library package has the same client hook type defined.
import (
"context"
"google.golang.org/api/option"
)
type clientHookParams struct{}
type clientHook func(context.Context, clientHookParams) ([]option.ClientOption, error)A clientHook receives a context.Context and an instance of
clientHookParams, and returns a option.ClientOption slice.
The clientHookParams type provides flexibility to the client hook
interface. As new use cases are discovered, more data can be made available to
clientHook implementations through the clientHookParams.
Note: both types are part of the generated client content and cannot be manually edited.
Each service client has a service-specific, package-level variable of type
clientHook.
var newFooClientHook clientHookClient owners can implement a clientHook and assign it to one or many
service-specific clientHook variables as needed.
At runtime during client construction, if a client hook variable is assigned
an implementation, it is invoked with the same Context that was provided to
the constructor, and a clientHookParams struct. Client hook invocation
occurs prior to connection dialing.
Options are applied in the following order:
- Default options.
-
clientHookoptions. - User-supplied options.
So, user-supplied options have precedence over clientHook options, which have
precedence over default options.
-
The
Contextgiven to theclientHookmust be used as is. It must not be copied and mutated. This is to preserve user management ofContext. -
A
clientHookmust not explicitly usepanic. -
A
clientHookmust not emit log messages. -
All
clientHookimplementation code must be unexported. -
A
clientHookmust not add new dependencies. -
Every
clientHookimplementation must have tests. -
The
clientHookimplementation should be in a file namedhook.go.