This repo contains the source code for practicing golang concepts
Metadata is sent as HTTP/2 header
ctx = metadata.AppendToOutgoingContext(ctx, "x-interceptor", "client")
md, err := metadata.FromIncomingContext(ctx)
s := grpc.NewServer(grpc.UnaryInterceptor(serverInterceptor))
From the server interceptor, invoke other methods for functionalities like authentication, logging etc Make sure to pass the current context to those methods.
// Server Unary Interceptor
// It authorizes the request if 'authorization' header/metadata is present
// Note: function name can be anything, but its signature should match to UnaryServerInterceptor
func serverInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
// Invoke function for authorization
// Check if 'Authorization' header/metadata is set
if err := authorize(ctx); err != nil {
return nil, err
}
// Do not modify this
h, err := handler(ctx, req)
return h, err
}
con, err := grpc.Dial(serverAddress, grpc.WithUnaryInterceptor(clientInterceptor), grpc.WithInsecure())
Client interceptor is used to add metadata information (headers) before making request to the gRPC server
// This interceptor will add a metadata 'x-interceptor: client'
func clientInterceptor(ctx context.Context, method string, req interface{}, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
fmt.Println("clientInterceptor interceptor invoked")
// Add the metadata to the current context
// 'x-interceptor: client'
ctx = metadata.AppendToOutgoingContext(ctx, "x-interceptor", "client")
return invoker(ctx, method, req, reply, cc, opts...)
}