3.8 KiB
Executable File
title, category, order
title | category | order |
---|---|---|
Customizing your gateway | documentation | 101 |
Customizing your gateway
Message serialization
You might want to serialize request/response messages in MessagePack instead of JSON, for example.
- Write a custom implementation of
Marshaler
- Register your marshaler with
WithMarshalerOption
e.g.var m your.MsgPackMarshaler mux := runtime.NewServeMux(runtime.WithMarshalerOption("application/x-msgpack", m))
You can see the default implementation for JSON for reference.
Mapping from HTTP request headers to gRPC client metadata
You might not like the default mapping rule and might want to pass through all the HTTP headers, for example.
-
Write a
HeaderMatcherFunc
. -
Register the function with
WithIncomingHeaderMatcher
e.g.
func yourMatcher(headerName string) (mdName string, ok bool) { ... } ... mux := runtime.NewServeMux(runtime.WithIncomingHeaderMatcher(yourMatcher))
Mapping from gRPC server metadata to HTTP response headers
ditto. Use WithOutgoingHeaderMatcher
Mutate response messages or set response headers
You might want to return a subset of response fields as HTTP response headers; You might want to simply set an application-specific token in a header. Or you might want to mutate the response messages to be returned.
-
Write a filter function.
func myFilter(ctx context.Context, w http.ResponseWriter, resp proto.Message) error { w.Header().Set("X-My-Tracking-Token", resp.Token) resp.Token = "" return nil }
-
Register the filter with
WithForwardResponseOption
e.g.
mux := runtime.NewServeMux(runtime.WithForwardResponseOption(myFilter))
Error handler
http://mycodesmells.com/post/grpc-gateway-error-handler
Replace a response forwarder per method
You might want to keep the behavior of the current marshaler but change only a message forwarding of a certain API method.
-
write a custom forwarder which is compatible to
ForwardResponseMessage
orForwardResponseStream
. -
replace the default forwarder of the method with your one.
e.g. add
forwarder_overwrite.go
into the go package of the generated code,package generated import ( "net/http" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/golang/protobuf/proto" "golang.org/x/net/context" ) func forwardCheckoutResp(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { if someCondition(resp) { http.Error(w, "not enough credit", http. StatusPaymentRequired) return } runtime.ForwardResponseMessage(ctx, mux, marshaler, w, req, resp, opts...) } func init() { forward_MyService_Checkout_0 = forwardCheckoutResp }