snapshot of https://github.com/grpc/grpc-go.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
Testing / vet-proto (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
Testing / vet-proto (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s
This commit is contained in:
130
examples/features/interceptor/README.md
Normal file
130
examples/features/interceptor/README.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# 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](https://grpc.io/docs/guides/concepts.html#rpc-life-cycle) 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`](https://godoc.org/google.golang.org/grpc#UnaryClientInterceptor).
|
||||
It is a function type with signature:
|
||||
|
||||
```golang
|
||||
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`](https://godoc.org/google.golang.org/grpc#WithUnaryInterceptor)
|
||||
`DialOption`.
|
||||
|
||||
#### Stream Interceptor
|
||||
|
||||
The type for client-side stream interceptors is
|
||||
[`StreamClientInterceptor`](https://godoc.org/google.golang.org/grpc#StreamClientInterceptor).
|
||||
It is a function type with signature:
|
||||
|
||||
```golang
|
||||
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 overriding 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 (override) 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`](https://godoc.org/google.golang.org/grpc#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`](https://godoc.org/google.golang.org/grpc#UnaryServerInterceptor).
|
||||
It is a function type with signature:
|
||||
|
||||
```golang
|
||||
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`](https://godoc.org/google.golang.org/grpc#UnaryInterceptor)
|
||||
`ServerOption`.
|
||||
|
||||
#### Stream Interceptor
|
||||
|
||||
The type for server-side stream interceptors is
|
||||
[`StreamServerInterceptor`](https://godoc.org/google.golang.org/grpc#StreamServerInterceptor).
|
||||
It is a function type with the signature:
|
||||
|
||||
```golang
|
||||
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`](https://godoc.org/google.golang.org/grpc#StreamInterceptor)
|
||||
`ServerOption`.
|
||||
Reference in New Issue
Block a user