Package list golang-github-go-kit-kit / 4079d84
Improved gRPC Request / Response Funcs - Separated ClientRequestFunc and ServerRequestFunc to highlight that request metadata in a ServerRequestFunc is supposed to be immutable. - Return context in ServerResponseFuncs like with the HTTP transport, to allow passing data between chained serverAfter middlewares and finally to the encoding step so it can be used to alter the response payload prior to sending this response to the client. Bas van Beek 4 years ago
4 changed file(s) with 39 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
3737
3838 /* server before functions */
3939
40 func extractCorrelationID(ctx context.Context, md *metadata.MD) context.Context {
41 if hdr, ok := (*md)[string(correlationID)]; ok {
40 func extractCorrelationID(ctx context.Context, md metadata.MD) context.Context {
41 if hdr, ok := md[string(correlationID)]; ok {
4242 cID := hdr[len(hdr)-1]
4343 ctx = context.WithValue(ctx, correlationID, cID)
4444 fmt.Printf("\tServer received correlationID %q in metadata header, set context\n", cID)
4646 return ctx
4747 }
4848
49 func displayServerRequestHeaders(ctx context.Context, md *metadata.MD) context.Context {
50 if len(*md) > 0 {
49 func displayServerRequestHeaders(ctx context.Context, md metadata.MD) context.Context {
50 if len(md) > 0 {
5151 fmt.Println("\tServer << Request Headers:")
52 for key, val := range *md {
52 for key, val := range md {
5353 fmt.Printf("\t\t%s: %s\n", key, val[len(val)-1])
5454 }
5555 }
5858
5959 /* server after functions */
6060
61 func injectResponseHeader(ctx context.Context, md *metadata.MD, _ *metadata.MD) {
61 func injectResponseHeader(ctx context.Context, md *metadata.MD, _ *metadata.MD) context.Context {
6262 *md = metadata.Join(*md, metadata.Pairs(string(responseHDR), "has-a-value"))
63 return ctx
6364 }
6465
65 func displayServerResponseHeaders(ctx context.Context, md *metadata.MD, _ *metadata.MD) {
66 func displayServerResponseHeaders(ctx context.Context, md *metadata.MD, _ *metadata.MD) context.Context {
6667 if len(*md) > 0 {
6768 fmt.Println("\tServer >> Response Headers:")
6869 for key, val := range *md {
6970 fmt.Printf("\t\t%s: %s\n", key, val[len(val)-1])
7071 }
7172 }
73 return ctx
7274 }
7375
74 func injectResponseTrailer(ctx context.Context, _ *metadata.MD, md *metadata.MD) {
76 func injectResponseTrailer(ctx context.Context, _ *metadata.MD, md *metadata.MD) context.Context {
7577 *md = metadata.Join(*md, metadata.Pairs(string(responseTRLR), "has-a-value-too"))
78 return ctx
7679 }
7780
78 func injectConsumedCorrelationID(ctx context.Context, _ *metadata.MD, md *metadata.MD) {
81 func injectConsumedCorrelationID(ctx context.Context, _ *metadata.MD, md *metadata.MD) context.Context {
7982 if hdr, ok := ctx.Value(correlationID).(string); ok {
8083 fmt.Printf("\tServer found correlationID %q in context, set consumed trailer\n", hdr)
8184 *md = metadata.Join(*md, metadata.Pairs(string(correlationIDTRLR), hdr))
8285 }
86 return ctx
8387 }
8488
85 func displayServerResponseTrailers(ctx context.Context, _ *metadata.MD, md *metadata.MD) {
89 func displayServerResponseTrailers(ctx context.Context, _ *metadata.MD, md *metadata.MD) context.Context {
8690 if len(*md) > 0 {
8791 fmt.Println("\tServer >> Response Trailers:")
8892 for key, val := range *md {
8993 fmt.Printf("\t\t%s: %s\n", key, val[len(val)-1])
9094 }
9195 }
96 return ctx
9297 }
9398
9499 /* client after functions */
2020 enc EncodeRequestFunc
2121 dec DecodeResponseFunc
2222 grpcReply reflect.Type
23 before []RequestFunc
23 before []ClientRequestFunc
2424 after []ClientResponseFunc
2525 }
2626
5353 reflect.ValueOf(grpcReply),
5454 ).Interface(),
5555 ),
56 before: []RequestFunc{},
56 before: []ClientRequestFunc{},
5757 after: []ClientResponseFunc{},
5858 }
5959 for _, option := range options {
6767
6868 // ClientBefore sets the RequestFuncs that are applied to the outgoing gRPC
6969 // request before it's invoked.
70 func ClientBefore(before ...RequestFunc) ClientOption {
70 func ClientBefore(before ...ClientRequestFunc) ClientOption {
7171 return func(c *Client) { c.before = append(c.before, before...) }
7272 }
7373
1111 binHdrSuffix = "-bin"
1212 )
1313
14 // RequestFunc may take information from a gRPC request and put it into a
15 // request context. In Servers, RequestFuncs are executed prior to invoking the
16 // endpoint. In Clients, RequestFuncs are executed after creating the request
17 // but prior to invoking the gRPC client.
18 type RequestFunc func(context.Context, *metadata.MD) context.Context
14 // ClientRequestFunc may take information from context and use it to construct
15 // metadata headers to be transported to the server. ClientRequestFuncs are
16 // executed after creating the request but prior to sending the gRPC request to
17 // the server.
18 type ClientRequestFunc func(context.Context, *metadata.MD) context.Context
19
20 // ServerRequestFunc may take information from the received metadata header and
21 // use it to place items in the request scoped context. ServerRequestFuncs are
22 // executed prior to invoking the endpoint.
23 type ServerRequestFunc func(context.Context, metadata.MD) context.Context
1924
2025 // ServerResponseFunc may take information from a request context and use it to
2126 // manipulate the gRPC response metadata headers and trailers. ResponseFuncs are
2227 // only executed in servers, after invoking the endpoint but prior to writing a
2328 // response.
24 type ServerResponseFunc func(ctx context.Context, header *metadata.MD, trailer *metadata.MD)
29 type ServerResponseFunc func(ctx context.Context, header *metadata.MD, trailer *metadata.MD) context.Context
2530
2631 // ClientResponseFunc may take information from a gRPC metadata header and/or
2732 // trailer and make the responses available for consumption. ClientResponseFuncs
2934 // being decoded.
3035 type ClientResponseFunc func(ctx context.Context, header metadata.MD, trailer metadata.MD) context.Context
3136
32 // SetRequestHeader returns a RequestFunc that sets the specified metadata
37 // SetRequestHeader returns a ClientRequestFunc that sets the specified metadata
3338 // key-value pair.
34 func SetRequestHeader(key, val string) RequestFunc {
39 func SetRequestHeader(key, val string) ClientRequestFunc {
3540 return func(ctx context.Context, md *metadata.MD) context.Context {
3641 key, val := EncodeKeyValue(key, val)
3742 (*md)[key] = append((*md)[key], val)
4247 // SetResponseHeader returns a ResponseFunc that sets the specified metadata
4348 // key-value pair.
4449 func SetResponseHeader(key, val string) ServerResponseFunc {
45 return func(_ context.Context, md *metadata.MD, _ *metadata.MD) {
50 return func(ctx context.Context, md *metadata.MD, _ *metadata.MD) context.Context {
4651 key, val := EncodeKeyValue(key, val)
4752 (*md)[key] = append((*md)[key], val)
53 return ctx
4854 }
4955 }
5056
5157 // SetResponseTrailer returns a ResponseFunc that sets the specified metadata
5258 // key-value pair.
5359 func SetResponseTrailer(key, val string) ServerResponseFunc {
54 return func(_ context.Context, _ *metadata.MD, md *metadata.MD) {
60 return func(ctx context.Context, _ *metadata.MD, md *metadata.MD) context.Context {
5561 key, val := EncodeKeyValue(key, val)
5662 (*md)[key] = append((*md)[key], val)
63 return ctx
5764 }
5865 }
5966
2020 e endpoint.Endpoint
2121 dec DecodeRequestFunc
2222 enc EncodeResponseFunc
23 before []RequestFunc
23 before []ServerRequestFunc
2424 after []ServerResponseFunc
2525 logger log.Logger
2626 }
5353
5454 // ServerBefore functions are executed on the HTTP request object before the
5555 // request is decoded.
56 func ServerBefore(before ...RequestFunc) ServerOption {
56 func ServerBefore(before ...ServerRequestFunc) ServerOption {
5757 return func(s *Server) { s.before = append(s.before, before...) }
5858 }
5959
7878 }
7979
8080 for _, f := range s.before {
81 ctx = f(ctx, &md)
81 ctx = f(ctx, md)
8282 }
83
84 // Store potentially updated metadata in the gRPC context.
85 ctx = metadata.NewContext(ctx, md)
8683
8784 request, err := s.dec(ctx, req)
8885 if err != nil {
9895
9996 var mdHeader, mdTrailer metadata.MD
10097 for _, f := range s.after {
101 f(ctx, &mdHeader, &mdTrailer)
98 ctx = f(ctx, &mdHeader, &mdTrailer)
10299 }
103100
104101 grpcResp, err := s.enc(ctx, response)