Giter Site home page Giter Site logo

benmargolin / go-grpc-middleware Goto Github PK

View Code? Open in Web Editor NEW

This project forked from grpc-ecosystem/go-grpc-middleware

0.0 2.0 0.0 37 KB

Golang gRPC Middleware Helpers: interceptor chaining, context propagation etc.

License: Apache License 2.0

Go 98.21% Makefile 0.37% Protocol Buffer 1.41%

go-grpc-middleware's Introduction

Go gRPC Middleware - Interceptor Helpers

Travis Build Go Report Card GoDoc Apache 2.0 License

gRPC Go Interceptor middleware. Chain them, wrap them... arrange them in any pattern that normal http.Handler middleware would do :)

Interceptors

gRPC Go recently acquired support for Interceptors, i.e. middleware that is executed either on the gRPC Server before the request is passed onto the user's application logic, or on the gRPC client either around the user call. It is a perfect way to implement common patters: auth, logging, or monitoring (e.g. Prometheus)

Unfortunately out of the box, grpc-go allows you to have only one interceptor, which means you need to implement multiple interceptors manually... every time.

This repo contains tooling for gRPC interceptors, allowing you to achieve what many people do with HTTP middleware: auth, logging, pre-processing etc.

Chaining

Simple way of turning a multiple interceptors into a single interceptor. E.g.

Server

import "github.com/mwitkow/go-grpc-middleware"

myServer := grpc.NewServer(
    grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
    grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary),
)

These interceptors will be executed from left to right: logging, monitoring and auth.

Client

clientConn, err = grpc.Dial(
    address,
        grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
        grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
)
client = pb_testproto.NewTestServiceClient(clientConn)
resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})

These interceptors will be executed from left to right: monitoring and then retry logic. Interestingly, the retry logic may perform more than one RPC.

How to write Interceptors?

It is incredibly useful to pass values around from one interceptor to another, similarly to HTTP Middleware design. For example, you may want to pass the identity of the caller from the auth interceptor all the way to the calling function.

Context Propagation

Unary (1:1) RPCs

This is relatively simple, since context.Context is appendable, for example:

func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
   newCtx := context.WithValue(ctx, "user_id", "[email protected]")
   return handler(newCtx, req)
}

Streaming (N:1, 1:M, N:M) RPCs

Unfortunately, it's not as easy for streaming RPCs. These have the context.Context embedded within the grpc.ServerStream object. To pass values through context, a wrapper (WrappedServerStream) is needed. For example:

func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
   newStream := grpc_middleware.WrapServerStream(stream)
   newStream.WrappedContext = context.WithValue(stream.Context(), "user_id", "[email protected]")
   return handler(srv, stream)
}

Status

This code has been inspired by the gRPC interceptor design discussion, and the upstream PR.

This code has been running in production since May 2016 as the basis of the gRPC micro services stack at Improbable.

Additional tooling will be added, and contributions are welcome.

License

go-grpc-middleware is released under the Apache 2.0 license. See the LICENSE file for details.

go-grpc-middleware's People

Contributors

benmargolin avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.