Add request message field values to context

203 views
Skip to first unread message

Hans Wustrack

unread,
Sep 23, 2022, 11:15:52 AM9/23/22
to grpc.io
Hi all,

I'm implementing a simple resource oriented API with a gRPC server. Every request message type will have a 'name' field (or similar) that specifies the resource to be operated on. I would like to add the value of that name field to the gRPC context on every request, so it can be used later in application code.

As this is an action I'd like to perform on every request, a ServerInteceptor seemed like an appropriate place to add this bit of functionality. In implementing, I've taken inspiration from previous questions here and on the github repo:

Our server will only accept unary calls, so the pattern of delaying next.startCall() by setting a NOOP listener until we receive the first message seems okay for our use case. In OnMessage, we'll parse the request message and call Contexts.interceptCall with the necessary info from the request.

I have a few questions about this approach:

- We need to call call.request(1) to initiate the request for the first message (as discussed in grpc-io/c/_osH2D6L9Ck). Would this create issues if we need more than one ServerInterceptor of this type? I.e. we'd have multiple interceptors initially with NOOP listeners delaying the call and calling call.request(1).

- I couldn't find many examples of implementing a ServerInterceptor that adds a piece of information from a request message to the context. Should we consider other ways of handling this like including the necessary values in Metadata or adding to context in the handlers?

Thanks!

Sanjay Pujare

unread,
Sep 23, 2022, 1:40:52 PM9/23/22
to Hans Wustrack, grpc.io
Instead of messing with interceptors (since you are not dealing with metadata) have you considered just using methods related to context(s)? e.g. on the server side you can just restructure your existing stub code and do something like

public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
String resource = req.getName();
  MyCallable callable = new MyCallable(); // your server code is in MyCallable
  result = Context.current().withValue(ResourceNameKey, resource).wrap(callable);
  responseObserver.onNext(result);
}

I think this is much easier than using an interceptor and/or delaying the call etc. Or else you can have the client itself insert the resource name in Metadata in which case the serverInterceptor can read that and add it to the server context. Hopefully you know how to do that.

--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/e6463490-403d-4140-8a37-76477541491dn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages