In io.grpc.internal.AbstractServerImplBuilder you may add implementations of the ServerInterceptor to the final list
final List<ServerInterceptor> interceptors = new ArrayList<>();
then in default server implementation for the builder - io.grpc.internal.ServerImpl it calls them in the foreach loop
/** Never returns {@code null}. */
private <ReqT, RespT> ServerStreamListener startCall(ServerStream stream, String fullMethodName,
ServerMethodDefinition<ReqT, RespT> methodDef, Metadata headers,
Context.CancellableContext context, StatsTraceContext statsTraceCtx, Tag tag) {
// TODO(ejona86): should we update fullMethodName to have the canonical path of the method?
statsTraceCtx.serverCallStarted(
new ServerCallInfoImpl<>(
methodDef.getMethodDescriptor(), // notify with original method descriptor
stream.getAttributes(),
stream.getAuthority()));
ServerCallHandler<ReqT, RespT> handler = methodDef.getServerCallHandler();
for (ServerInterceptor interceptor : interceptors) {
handler = InternalServerInterceptors.interceptCallHandler(interceptor, handler);
}
ServerMethodDefinition<ReqT, RespT> interceptedDef = methodDef.withServerCallHandler(handler);
ServerMethodDefinition<?, ?> wMethodDef = binlog == null
? interceptedDef : binlog.wrapMethodDefinition(interceptedDef);
return startWrappedCall(fullMethodName, wMethodDef, stream, headers, context, tag);
}
so it executes the interceptors chain from the last registered to the former one when received the request. Same order is followed when doing the response from the handler.
What I wonder and expected is that it will follow onion middleware pattern and you can explicitly set the execution order (similar to the servlet filters). Do I miss something?