Skip to content

Commit

Permalink
Gateways wrap response writer w/ negroni so their MW works out of the…
Browse files Browse the repository at this point in the history
… box. (#60)
  • Loading branch information
robsignorelli authored Sep 27, 2021
1 parent 4d2dabd commit a4d230a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/monadicstack/respond v0.4.2
github.com/spf13/cobra v1.1.1
github.com/stretchr/testify v1.6.1
github.com/urfave/negroni v1.0.0
golang.org/x/mod v0.4.0
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
Expand Down
21 changes: 20 additions & 1 deletion rpc/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/monadicstack/frodo/rpc/authorization"
"github.com/monadicstack/frodo/rpc/metadata"
"github.com/monadicstack/respond"
"github.com/urfave/negroni"
)

// NewGateway creates a wrapper around your raw service to expose it via HTTP for RPC calls.
Expand Down Expand Up @@ -124,8 +125,26 @@ func (gw Gateway) registerOptions(path string) {

// ServeHTTP is the central HTTP handler that includes all http routing, middleware, service forwarding, etc.
func (gw Gateway) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Why the negroni response writer?
//
// https://github.com/monadicstack/frodo/issues/50
//
// Since negroni is basically the de facto HTTP middleware for go, I want to support their
// out-of-the-box functions as much as possible. Unfortunately their logger middleware will
// panic if it does not receive their own ResponseWriter interface:
//
// https://github.com/urfave/negroni/blob/master/logger.go#L63
//
// It's not a huge issue to them because they expect you to take all of their middleware functions
// and use 'negroni.New()' to construct a single http.Handler. When that handler is invoked, they'll
// gladly wrap the writer w/ their custom one, and it works. Frodo does its own middleware function
// combining so their implicit wrapping never happens. Since we'd like you to be able to
// use as much off the shelf as possible w/o weird glue code, we'll do the same wrapping to satisfy
// the overly-tight coupling of the most common middleware library in the Go ecosystem.
//
// tldr; Frodo doesn't use the wrapped writer for anything special. It's just to keep negroni from barfing.
ctx := context.WithValue(req.Context(), contextKeyGateway{}, &gw)
gw.Router.ServeHTTP(w, req.WithContext(ctx))
gw.Router.ServeHTTP(negroni.NewResponseWriter(w), req.WithContext(ctx))
}

// Endpoint describes an operation that we expose through an RPC gateway.
Expand Down

0 comments on commit a4d230a

Please sign in to comment.