- Author(s): murgatroid99, WeiranFang
- Approver: wenbozhu
- Status: Draft
- Implemented in: Node
- Last updated: 26-09-2018
- Discussion at: https://groups.google.com/forum/#!topic/grpc-io/f3v4SBvj7L4
Add a client API for transforming some parameters and intermediate variables for each call made using that client.
Some advanced call interception use cases, such as content-based channel affinity, require functionality that is not provided by the existing CallInterceptor
API.
Define the type CallContext
as follows:
interface CallContext {
// The argument to the method. Only available for unary and client-streaming methods
argument: any;
// The metadata that will be sent to that data
metadata: Metadata;
// The call object that will be returned by the method
call: ClientUnaryCall | ClientReadableStream | ClientWritableStream | ClientDuplexStream;
// The channel object that will be used to transmit the request
channel: Channel;
// An object describing the request method
methodDefinition: MethodDefinition;
// The options object passed to the call
callOptions: CallOptions;
// The callback passed to the method. Only available for unary and client-streaming methods
callback: requestCallback;
}
Add a new option to the Client
constructor options
parameter called callInvocationTransformer
, that accepts a function that takes a CallContext
object as an input and returns another CallContext
object as the output. This function can read and modify any of the values in the object, and the returned values will be used for processing the request, with the caveat that some modifications may cause the request to be processed improperly.
The specific use case that prompted this proposal needs change the channel based on the unserialized argument, and to track response messages and call start and end associated with each channel. The only part of the code with access to all of those things is the beginning of each call invocation function in the client. So, for generality, this API provides access to a set of objects that consistently describe the inputs and state that determine how a call is invoked, including the ones that the mentioned use case needs.
The implementation in the grpc
library will be completed by @WeiranFang after this proposal is accepted. An initial implementation PR exists at grpc/grpc-node#557.
The implementation in the @grpc/grpc-js
library will be completed by @murgatroid99 after the client interceptors API is implemented in that library.