interceptor/

directory
v0.0.0-...-e22436a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2024 License: Apache-2.0

README

Interceptor

gRPC provides simple APIs to implement and install interceptors on a per ClientConn/Server basis. Interceptors act as a layer between the application and gRPC and can be used to observe or control the behavior of gRPC. Interceptors can be used for logging, authentication/authorization, metrics collection, and other functionality that is shared across RPCs.

Try it

go run server/main.go
go run client/main.go

Explanation

gRPC has separate interceptors for unary RPCs and streaming RPCs. See the gRPC docs for an explanation about unary and streaming RPCs. Both the client and the server have their own types of unary and stream interceptors. Thus, there are four different types of interceptors in total.

Client-side
Unary Interceptor

The type for client-side unary interceptors is UnaryClientInterceptor. It is essentially a function type with signature: func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error. Unary interceptor implementations can usually be divided into three parts: pre-processing, invoking the RPC method, and post-processing.

For pre-processing, users can get info about the current RPC call by examining the args passed in. The args include the RPC context, method string, request to be sent, and the CallOptions configured. With this info, users can even modify the RPC call. For instance, in the example, we examine the list of CallOptions and check if the call credentials have been configured. If not, the interceptor configures the RPC call to use oauth2 with a token "some-secret-token" as a fallback. In our example, we intentionally omit configuring the per RPC credential to resort to the fallback.

After pre-processing, users can invoke the RPC call by calling the invoker.

Once the invoker returns, users can post-process the RPC call. This usually involves dealing with the returned reply and error. In the example, we log the RPC timing and error info.

To install a unary interceptor on a ClientConn, configure Dial with the WithUnaryInterceptor DialOption.

Stream Interceptor

The type for client-side stream interceptors is StreamClientInterceptor. It is a function type with signature: func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error). An implementation of a stream interceptor usually includes pre-processing, and stream operation interception.

The pre-processing is similar to unary interceptors.

However, rather than invoking the RPC method followed by post-processing, stream interceptors intercept the users' operations on the stream. The interceptor first calls the passed-in streamer to get a ClientStream, and then wraps the ClientStream while overloading its methods with the interception logic. Finally, the interceptor returns the wrapped ClientStream to user to operate on.

In the example, we define a new struct wrappedStream, which embeds a ClientStream. We then implement (overload) the SendMsg and RecvMsg methods on wrappedStream to intercept these two operations on the embedded ClientStream. In the example, we log the message type info and time info for interception purpose.

To install a stream interceptor for a ClientConn, configure Dial with the WithStreamInterceptor DialOption.

Server-side

Server side interceptors are similar to client side interceptors, with slightly different information provided as args.

Unary Interceptor

The type for server-side unary interceptors is UnaryServerInterceptor. It is a function type with signature: func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error).

Refer to the client-side unary interceptor section for a detailed implementation and explanation.

To install a unary interceptor on a Server, configure NewServer with the UnaryInterceptor ServerOption.

Stream Interceptor

The type for server-side stream interceptors is StreamServerInterceptor. It is a function type with the signature: func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error.

Refer to the client-side stream interceptor section for a detailed implementation and explanation.

To install a stream interceptor on a Server, configure NewServer with the StreamInterceptor ServerOption.

Directories

Path Synopsis
Binary client is an example client.
Binary client is an example client.
Binary server is an example server.
Binary server is an example server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL