-
Notifications
You must be signed in to change notification settings - Fork 764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Proposal - Client Interceptors #558
Conversation
|
||
*Do not modify the listener passed in. Either pass it along unmodified or call methods on it to short-circuit the interceptor stack.* | ||
|
||
The `listener` methods are: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I'm not 100% convinced on the listener
API for inbound operations.
This has been ported from the NodeJS API; however I believe that this is over-complicated for the web implementation.
The way I see it, there only a few places where we need to intercept:
https://github.com/grpc/grpc-web/blob/master/javascript/net/grpc/web/grpcwebclientbase.js#L66
GrpcWebClientBase.prototype.rpcCall = function(
method, request, metadata, methodInfo, callback) {
// Intercept HERE onStart()
// ...
stream.on('data'); // Intercept HERE onData()
stream.on('status'); // Intercept HERE onStatus()
stream.on('error'); // Intercept HERE onError()
// ...
// Intercept HERE onSend()
xhr.send(method, 'POST', payload);
return stream;
};
The serverStreaming
is similar.
This would simplify the requester
object to:
var requester = {
onStart: function(metadata, next){},
onSend: function(request, next){},
onData: function(response, next){},
onStatus: function(status, next){},
onError: function(error, next){},
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A case can be made to keep the API design consistent with other platforms. That way developers don't need to re-learn concepts. For instance, I find it convenient that the Java API[1] is the same for Android and server. A ClientCall in Java roughly translates to InterceptingCall as defined in this proposal. So defining a Listener means the JS API looks similar to the Java API.
OTOH, the ObjC Interceptor API proposal does not define the concept of Listener and instead puts all methods on GRPCInterceptorInterface[2] instead.
[1]https://grpc.github.io/grpc-java/javadoc/io/grpc/ClientCall.html#start-io.grpc.ClientCall.Listener-io.grpc.Metadata-
[2]https://github.com/grpc/proposal/blob/9bcd06aae8e6f9122885711a602ecdc9af75c560/L50-objc-interceptor.md#interceptor-chain
* @param {string} options.hostname The server host to call | ||
* @param {Object} options.credentials Credentials used to authenticate with the server | ||
* @param {MethodDescriptor} options.methodDiscriptor A container of properties describing the call (see below) | ||
* @param {Function} nexCall Constructs the next interceptor in the chain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nexCall -> nextCall 🙂
Thanks for this! It looks great. 😄 |
* @param {MethodType} methodType One of two types: MethodType.UNARY or MethodType.SERVER_STREAMING | ||
* @param {grpc.web.AbstractClientBase.MethodInfo} methodInfo Properties containing the serialize and deserialize functions | ||
*/ | ||
MethodDescriptor(name, serviceName, path, methodType, methodInfo) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wdyt about moving the existing class out of AbstractClientBase and creating grpc.web.MethodInfo that works for this and other use cases?
Couple of reasons to consider this:
- If grpc.web.MethodInfo also contains the path it should simplify the proto compiler as well (js_grpc_web_library).
- It'll be confusing to have both MethodInfo and MethodDescriptor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I think this would be a good idea.
My initial thoughts on the implementation was to make minimal changes to the current API and CodeGen and provide backward compatibility (hence keeping methodInfo
as-is). The reality may be that the refactor may not be compatible... we would need to make a call on backward compatibility support; if no then this would push this project to v2.0.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi, #567 introduced grpc.web.MethodDescriptor and MethodType.
```javascript | ||
/** | ||
* An interception method called before an outbound call has started. | ||
* @param {grpc.web.Metadata} metadata The call's outbound metadata (request headers). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is grpc.web.Metadata a new class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I stole this from the TypeScript definition:
https://github.com/grpc/grpc-web/blob/master/packages/grpc-web/index.d.ts#L3
I probably should have left it as Object<string, string>
|
||
#### At call invocation | ||
|
||
If an array of interceptors is provided at call invocation via `options.interceptors`, the call will ignore all interceptors provided via the client constructor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why ignore vS add to end of list? Do you have some concerns about interceptor ordering?
Interceptors like authorization, logging, metrics collection are likely to be defined and configured centrally. It would be unfortunate if a call site that just wants to add a custom interceptor needs to redefine this entire list again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect that most interceptor authors to have there interceptor chains easily available to add at call invocation.
Yes, the main reason is the ordering, or possibly you want a different authorization
mechanism for that call etc.
I still think that this API has to override those at the client level, however maybe there is a second API that allows you to add
interceptors to the chain? This would be useful for tools to inject interceptors; for example the grpc-web chrome DevTools.
Hey @stanley-cheung what's holding this PR? It would be useful to have a clean way to refresh client side tokens. Perhaps even provide a JWT interceptor with the distribution. Something like https://github.com/avast/grpc-java-jwt |
I need grpc web client intercepter. |
@duncandean how about this now ? |
@duncandean hello...? |
@kahirokunn I'm not a reviewer authorised with write access. This proposal probably also needs more thoughts and comments. |
I see... 😢 |
I think this PR is necessary |
How are things going on this? |
We will be picking this up soon, sorry for the delay. |
Hi @rogchap, and everyone else who is interested in interceptors: First we are sorry it took us so long to get our act on this - resources, priorities, blablabla :) But we had not been idle on this - over the last many months, we have done some investigation internally to see how we can have a unified implementations of interceptors that will satisfy both our internal use case and the open source use case here. We have some designs and discussions internally to see how we will approach this. Also we identified some issues and requirements with the existing APIs that kind of get in our way for some of the features we plan internally. So over the last few months we had done some background work to introduce a few concepts like We are at a stage where we are close to be able to put a PR forward in the coming days to show how we plan to implement interceptors here in this repo. I have started a thread over at #766 to talk about how the interceptors are designed and provided some examples there. This is still work-in-progress - we are still working through some issues. Please check these out and let us know how you think! Thanks. |
* fix test warning * A flag for grpcWebProxy to allow to propagate some request headers The commit also fix grpcweb.WrappedGrpcServer header propagation to gRPC in case of using websockets Closes grpc#548
No description provided.