1
1
# Interceptor
2
2
3
3
gRPC provides simple APIs to implement and install interceptors on a per
4
- ClientConn/Server basis. Interceptor intercepts the execution of each RPC call.
5
- Users can use interceptors to do logging, authentication/authorization, metrics
6
- collection, and many other functionality that can be shared across RPCs.
4
+ ClientConn/Server basis. An interceptor intercepts the execution of each RPC
5
+ call. Users can use interceptors for logging, authentication/authorization,
6
+ metrics collection, and other functionality that can be shared across RPCs.
7
7
8
8
## Try it
9
9
@@ -17,102 +17,104 @@ go run client/main.go
17
17
18
18
## Explanation
19
19
20
- In gRPC, interceptors can be categorized into two kinds in terms of the type of
21
- RPC calls they intercept. The first one is the ** unary interceptor** , which
22
- intercepts unary RPC calls. And the other is the ** stream interceptor** which
23
- deals with streaming RPC calls. See
24
- [ here ] ( https://grpc.io/docs/guides/concepts.html#rpc-life-cycle ) for explanation
25
- about unary RPCs and streaming RPCs. Each of client and server has their own
26
- types of unary and stream interceptors. Thus, there are in total four different
27
- types of interceptors in gRPC .
20
+ In gRPC, interceptors can be categorized into two kinds based on the type of RPC
21
+ calls they intercept. The first one is the ** unary interceptor** , which
22
+ intercepts unary RPC calls. The second is the ** stream interceptor** which deals
23
+ with streaming RPC calls. See the
24
+ [ gRPC docs ] ( https://grpc.io/docs/guides/concepts.html#rpc-life-cycle ) for an
25
+ explanation about unary and streaming RPCs. Both the client and the server have
26
+ their own types of unary and stream interceptors. Thus, there are four different
27
+ types of interceptors in total .
28
28
29
29
### Client-side
30
30
31
31
#### Unary Interceptor
32
32
33
- [ ` UnaryClientInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#UnaryClientInterceptor )
34
- is the type for client-side unary interceptor. It is essentially a function type
35
- with signature: `func(ctx context.Context, method string, req, reply
36
- interface{}, cc * ClientConn, invoker UnaryInvoker, opts ...CallOption) error`.
37
- An implementation of a unary interceptor can usually be divided into three
38
- parts: pre-processing, invoking RPC method, and post-processing.
33
+ The type for client-side unary interceptors is
34
+ [ ` UnaryClientInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#UnaryClientInterceptor ) .
35
+ It is essentially a function type with signature: `func(ctx context.Context,
36
+ method string, req, reply interface{}, cc * ClientConn, invoker UnaryInvoker,
37
+ opts ...CallOption) error`. Unary interceptor implementations can usually be
38
+ divided into three parts: pre-processing, invoking the RPC method, and
39
+ post-processing.
39
40
40
41
For pre-processing, users can get info about the current RPC call by examining
41
- the args passed in, such as RPC context, method string, request to be sent, and
42
- CallOptions configured. With the info, users can even modify the RPC call. For
43
- instance, in the example, we examine the list of CallOptions and see if call
44
- credential has been configured. If not, configure it to use oauth2 with token
45
- "some-secret-token" as fallback. In our example, we intentionally omit
46
- configuring the per RPC credential to resort to fallback.
47
-
48
- After pre-processing is done, use can invoke the RPC call by calling the
49
- ` invoker ` .
50
-
51
- Once the invoker returns the reply and error, user can do post-processing of the
52
- RPC call. Usually, it's about dealing with the returned reply and error. In the
42
+ the args passed in. The args include the RPC context, method string, request to
43
+ be sent, and the CallOptions configured. With this info, users can even modify
44
+ the RPC call. For instance, in the example, we examine the list of CallOptions
45
+ and check if the call credentials have been configured. If not, the interceptor
46
+ configures the RPC call to use oauth2 with a token "some-secret-token" as a
47
+ fallback. In our example, we intentionally omit configuring the per RPC
48
+ credential to resort to the fallback.
49
+
50
+ After pre-processing, users can invoke the RPC call by calling the ` invoker ` .
51
+
52
+ Once the invoker returns a reply and error, users can do post-processing of the
53
+ RPC call. It usually involves dealing with the returned reply and error. In the
53
54
example, we log the RPC timing and error info.
54
55
55
- To install a unary interceptor on a ClientConn, configure ` Dial ` with
56
- ` DialOption `
57
- [ ` WithUnaryInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#WithUnaryInterceptor ) .
56
+ To install a unary interceptor on a ClientConn, configure ` Dial ` with the
57
+ [ ` WithUnaryInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#WithUnaryInterceptor )
58
+ ` DialOption ` .
58
59
59
60
#### Stream Interceptor
60
61
61
- [ ` StreamClientInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#StreamClientInterceptor )
62
- is the type for client-side stream interceptor. It is a function type with
63
- signature: `func(ctx context.Context, desc * StreamDesc, cc * ClientConn, method
64
- string, streamer Streamer, opts ...CallOption) (ClientStream, error)`. An
65
- implementation of a stream interceptor usually include pre-processing, and
66
- stream operation interception.
67
-
68
- For pre-processing, it's similar to unary interceptor .
69
-
70
- However, rather than doing the RPC method invocation and post-processing
71
- afterwards, stream interceptor intercepts the users' operation on the stream.
72
- First, the interceptor calls the passed-in ` streamer ` to get a ` ClientStream ` ,
73
- and then wraps around the ` ClientStream ` and overloading its methods with
74
- intercepting logic. Finally, interceptors returns the wrapped ` ClientStream ` to
75
- user to operate on.
76
-
77
- In the example, we define a new struct ` wrappedStream ` , which is embedded with a
78
- ` ClientStream ` . Then, we implement (overload) the ` SendMsg ` and ` RecvMsg `
79
- methods on ` wrappedStream ` to intercept these two operations on the embedded
62
+ The type for client-side stream interceptors is
63
+ [ ` StreamClientInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#StreamClientInterceptor ) .
64
+ It is a function type with signature: `func(ctx context.Context, desc
65
+ * StreamDesc, cc * ClientConn, method string, streamer Streamer, opts
66
+ ...CallOption) (ClientStream, error)`. An implementation of a stream interceptor
67
+ usually includes pre-processing, and stream operation interception.
68
+
69
+ The pre-processing is similar to unary interceptors .
70
+
71
+ However, rather than invoking the RPC method followed by post-processing, stream
72
+ interceptors intercept the users' operations on the stream. The interceptor
73
+ first calls the passed-in ` streamer ` to get a ` ClientStream ` , and then wraps
74
+ around the ` ClientStream ` while overloading its methods with the interception
75
+ logic. Finally, the interceptor returns the wrapped ` ClientStream ` to user to
76
+ operate on.
77
+
78
+ In the example, we define a new struct ` wrappedStream ` , which embeds a
79
+ ` ClientStream ` . We then implement (overload) the ` SendMsg ` and ` RecvMsg ` methods
80
+ on ` wrappedStream ` to intercept these two operations on the embedded
80
81
` ClientStream ` . In the example, we log the message type info and time info for
81
82
interception purpose.
82
83
83
- To install the stream interceptor for a ClientConn, configure ` Dial ` with
84
- ` DialOption `
85
- [ ` WithStreamInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#WithStreamInterceptor ) .
84
+ To install a stream interceptor for a ClientConn, configure ` Dial ` with the
85
+ [ ` WithStreamInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#WithStreamInterceptor )
86
+ ` DialOption ` .
86
87
87
88
### Server-side
88
89
89
- Server side interceptor is similar to client side, though with slightly
90
- different provided info .
90
+ Server side interceptors are similar to client side interceptors, with slightly
91
+ different information provided as args .
91
92
92
93
#### Unary Interceptor
93
94
94
- [ ` UnaryServerInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#UnaryServerInterceptor )
95
- is the type for server-side unary interceptor. It is a function type with
96
- signature: `func(ctx context.Context, req interface{}, info * UnaryServerInfo,
97
- handler UnaryHandler) (resp interface{}, err error)`.
95
+ The type for server-side unary interceptor is
96
+ [ ` UnaryServerInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#UnaryServerInterceptor ) .
97
+ It is a function type with signature: `func(ctx context.Context, req
98
+ interface{}, info * UnaryServerInfo, handler UnaryHandler) (resp interface{}, err
99
+ error)`.
98
100
99
- Refer to client-side unary interceptor section for detailed implementation
100
- explanation.
101
+ Refer to the client-side unary interceptor section for a detailed implementation
102
+ and explanation.
101
103
102
- To install the unary interceptor for a Server, configure ` NewServer ` with
103
- ` ServerOption `
104
- [ ` UnaryInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#UnaryInterceptor ) .
104
+ To install a unary interceptor on a Server, configure ` NewServer ` with the
105
+ [ ` UnaryInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#UnaryInterceptor )
106
+ ` ServerOption ` .
105
107
106
108
#### Stream Interceptor
107
109
108
- [ ` StreamServerInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#StreamServerInterceptor )
109
- is the type for server-side stream interceptor. It is a function type with
110
- signature: `func(srv interface{}, ss ServerStream, info * StreamServerInfo,
111
- handler StreamHandler) error`.
110
+ The type for server-side stream interceptors is
111
+ [ ` StreamServerInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#StreamServerInterceptor ) .
112
+ It is a function type with the signature: `func(srv interface{}, ss
113
+ ServerStream, info * StreamServerInfo, handler StreamHandler) error`.
112
114
113
- Refer to client-side stream interceptor section for detailed implementation
114
- explanation.
115
+ Refer to the client-side stream interceptor section for a detailed
116
+ implementation and explanation.
115
117
116
- To install the stream interceptor for a Server, configure ` NewServer ` with
117
- ` ServerOption `
118
- [ ` StreamInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#StreamInterceptor ) .
118
+ To install a stream interceptor on a Server, configure ` NewServer ` with the
119
+ [ ` StreamInterceptor ` ] ( https://godoc.org/google.golang.org/grpc#StreamInterceptor )
120
+ ` ServerOption ` .
0 commit comments