quick implementation of middleware

This commit is contained in:
luke.rodham
2018-03-12 10:08:30 +00:00
parent 6740568afb
commit 1e787689aa
12 changed files with 187 additions and 84 deletions

114
Gopkg.lock generated
View File

@@ -3,9 +3,15 @@
[[projects]]
branch = "master"
name = "dmitri.shuralyov.com/kebabcase"
name = "dmitri.shuralyov.com/text/kebabcase"
packages = ["."]
revision = "bf160e40a7918fbe9dc3cc841a023d87242bd2eb"
revision = "40e40b42552a9cb37d6e98f4ad31f63ae53ea43a"
[[projects]]
branch = "master"
name = "github.com/cockroachdb/cockroach-go"
packages = ["crdb"]
revision = "59c0560478b705bf9bd12f9252224a0fad7c87df"
[[projects]]
name = "github.com/davecgh/go-spew"
@@ -14,16 +20,16 @@
version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/daviddengcn/go-colortext"
packages = ["."]
revision = "17e75f6184bc9e727756cd0d82e0af58b1fc7191"
version = "1.0.0"
[[projects]]
name = "github.com/fatih/color"
packages = ["."]
revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260"
version = "v1.5.0"
revision = "507f6050b8568533fb3f5504de8e5205fa62a114"
version = "v1.6.0"
[[projects]]
name = "github.com/fatih/structs"
@@ -40,32 +46,44 @@
[[projects]]
name = "github.com/gobuffalo/buffalo"
packages = ["render"]
revision = "4220930a985fea6cd3f207efa1f822940ab08c2b"
version = "v0.10.2"
revision = "bfa77a8652f7c8ec0bede640656c8add3cb230c2"
version = "v0.10.3"
[[projects]]
name = "github.com/gobuffalo/envy"
packages = ["."]
revision = "e613c80275b86293880eddeb27417c9a7c670ff3"
version = "v1.3.0"
revision = "197631a8f4c665cf7eeb157d5bc00d988419c4e7"
version = "v1.5.0"
[[projects]]
name = "github.com/gobuffalo/packr"
packages = ["."]
revision = "60f8243a040d5c5c80339403322a5a6fb56c2333"
version = "v1.9.10"
revision = "6434a292ac52e6964adebfdce3f9ce6d9f16be01"
version = "v1.10.4"
[[projects]]
name = "github.com/gobuffalo/plush"
packages = [".","ast","lexer","parser","token"]
revision = "f15814743c4d25c1bc5371e75d1ef51c9afdddba"
version = "v3.6.0"
revision = "a3df688902c0ccd9fa712ed5a1da6b78e7efab0d"
version = "v3.6.12"
[[projects]]
name = "github.com/gobuffalo/tags"
packages = [".","form","form/bootstrap"]
revision = "fd130d3e089cc2ae7285f7b4f3e45fd3f1aa3482"
version = "v1.9.0"
revision = "ab52126649ee51d858d9525f60bc1618592433b0"
version = "v2.0.0"
[[projects]]
name = "github.com/gobuffalo/uuid"
packages = ["."]
revision = "3a9fb6c5c481d4886f1e9323c61ad743fb955860"
version = "v2.0.0"
[[projects]]
name = "github.com/gobuffalo/validate"
packages = [".","validators"]
revision = "42d8db6e06e617cdedcc7a849d6690a2cb5a8d28"
version = "v2.0.0"
[[projects]]
name = "github.com/gorilla/context"
@@ -76,14 +94,14 @@
[[projects]]
name = "github.com/gorilla/mux"
packages = ["."]
revision = "7f08801859139f86dfafd1c296e2cba9a80d292e"
version = "v1.6.0"
revision = "53c1911da2b537f792e7cafcb446b05ffe33b996"
version = "v1.6.1"
[[projects]]
branch = "master"
name = "github.com/jmoiron/sqlx"
packages = [".","reflectx"]
revision = "de8647470aafe4854c976707c431dbe1eb2822c6"
revision = "cf35089a197953c69420c8d0cecda90809764b1d"
[[projects]]
name = "github.com/joho/godotenv"
@@ -95,7 +113,7 @@
branch = "master"
name = "github.com/lib/pq"
packages = [".","oid"]
revision = "83612a56d3dd153a94a629cd64925371c9adad78"
revision = "88edab0803230a3898347e77b474f8c1820a1f20"
[[projects]]
branch = "master"
@@ -107,25 +125,25 @@
branch = "master"
name = "github.com/markbates/inflect"
packages = ["."]
revision = "a12c3aec81a6a938bf584a4bac567afed9256586"
revision = "3e32b42850a9f09fac18a6c09bbd04325f51f732"
[[projects]]
name = "github.com/markbates/pop"
packages = [".","columns","fizz","fizz/translators"]
revision = "b75753936c38f382be88b1ea4221b771994996c9"
version = "3.41.10"
packages = [".","associations","columns","fizz","fizz/translators"]
revision = "f230643ae0f8fa01e9444c2fb857ba1f1a78eb1f"
version = "v4.0.0"
[[projects]]
branch = "master"
name = "github.com/markbates/validate"
packages = [".","validators"]
packages = ["."]
revision = "cd8cc34c703420d6b084fbbfd5085e8e71c5b830"
version = "v1.0.0"
[[projects]]
branch = "master"
name = "github.com/mattn/anko"
packages = ["ast","builtins","builtins/encoding/json","builtins/errors","builtins/flag","builtins/fmt","builtins/github.com/daviddengcn/go-colortext","builtins/io","builtins/io/ioutil","builtins/math","builtins/math/big","builtins/math/rand","builtins/net","builtins/net/http","builtins/net/url","builtins/os","builtins/os/exec","builtins/os/signal","builtins/path","builtins/path/filepath","builtins/regexp","builtins/runtime","builtins/sort","builtins/strconv","builtins/strings","builtins/time","parser","vm"]
revision = "3b446c7d031bdd754fc0183f599af173cd996715"
revision = "d5441ca3f0c7e071a9ede864f9db2cc652690f42"
[[projects]]
name = "github.com/mattn/go-colorable"
@@ -142,8 +160,8 @@
[[projects]]
name = "github.com/mattn/go-sqlite3"
packages = ["."]
revision = "ed69081a91fd053f17672236b0dd52ba7485e1a3"
version = "v1.4.0"
revision = "6c771bb9887719704b210e87e934f08be014bdb1"
version = "v1.6.0"
[[projects]]
branch = "master"
@@ -170,10 +188,10 @@
version = "v1.0.0"
[[projects]]
branch = "master"
name = "github.com/russross/blackfriday"
packages = ["."]
revision = "6d1ef893fcb01b4f50cb6e57ed7df3e2e627b6b2"
revision = "55d61fa8aa702f59229e6cff85793c22e580eaf5"
version = "v1.5.1"
[[projects]]
name = "github.com/satori/go.uuid"
@@ -187,10 +205,10 @@
revision = "a683aaf2d516deecd70cad0c72e3ca773ecfcef0"
[[projects]]
branch = "master"
name = "github.com/sergi/go-diff"
packages = ["diffmatchpatch"]
revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
version = "v1.0.0"
[[projects]]
branch = "master"
@@ -202,7 +220,7 @@
branch = "master"
name = "github.com/shurcooL/go"
packages = ["parserutil","printerutil","reflectfind","reflectsource"]
revision = "004faa6b0118cf52635363b72b51cdcc297800a2"
revision = "364c5ae8518b51f5fda954762864d6f4d5c30c89"
[[projects]]
branch = "master"
@@ -214,7 +232,7 @@
branch = "master"
name = "github.com/shurcooL/graphql"
packages = ["ident"]
revision = "d0549edd16dceb6939e538fdb1b4f2ec7ee816cc"
revision = "3d276b9dcc6b1e0adf19557a8de5cb8632c07697"
[[projects]]
branch = "master"
@@ -232,7 +250,7 @@
branch = "master"
name = "github.com/shurcooL/octiconssvg"
packages = ["."]
revision = "38b02129bb6460858e11f90798a3832da1e502bd"
revision = "91d14858bf8188ba5143d67a3a677ea559000b0a"
[[projects]]
branch = "master"
@@ -240,6 +258,12 @@
packages = ["."]
revision = "86672fcb3f950f35f2e675df2240550f2a50762f"
[[projects]]
name = "github.com/sirupsen/logrus"
packages = ["."]
revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc"
version = "v1.0.5"
[[projects]]
branch = "master"
name = "github.com/sourcegraph/annotate"
@@ -255,14 +279,20 @@
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert","require"]
revision = "b91bfb9ebec76498946beb6af7c0230c7cc7ba6c"
version = "v1.2.0"
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = ["ssh/terminal"]
revision = "c7dcf104e3a7a1417abc0230cb0d5240d764159d"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = ["context","html","html/atom"]
revision = "d866cfc389cec985d6fda2859936a575a55a3ab6"
revision = "ae89d30ce0c63142b652837da33d782e2b0a9b25"
[[projects]]
branch = "master"
@@ -273,18 +303,18 @@
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix"]
revision = "28a7276518d399b9634904daad79e18b44d481bc"
packages = ["unix","windows"]
revision = "c28acc882ebcbfbe8ce9f0f14b9ac26ee138dd51"
[[projects]]
branch = "v2"
name = "gopkg.in/yaml.v2"
packages = ["."]
revision = "c95af922eae69f190717a0b7148960af8c55a072"
revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5"
version = "v2.1.1"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "5163286dab1e7d44b868e3b51dd6e9b26a3e0453511a704264e72c518f760856"
inputs-digest = "686f5e2aed8b743dfbc53e74a1e48185702059972b7a587db36af49ec0eeea8f"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -8,7 +8,7 @@
[[constraint]]
name = "github.com/gorilla/mux"
version = "1.6.0"
version = "1.6.1"
[[constraint]]
name = "github.com/stretchr/testify"
@@ -17,3 +17,6 @@
[[override]]
name = "github.com/satori/go.uuid"
revision = "36e9d2ebbde5e3f13ab2e25625fd453271d6522e"
[[constraint]]
name = "github.com/sirupsen/logrus"
version = "1.0.5"

View File

@@ -6,6 +6,7 @@ import (
"net/url"
"github.com/gobuffalo/buffalo/render"
"github.com/sirupsen/logrus"
)
type Context interface {
@@ -18,4 +19,5 @@ type Context interface {
Render(status int, rr render.Renderer) error
Redirect(status int, url string) error
Env() string
Logger() *logrus.Logger
}

View File

@@ -9,12 +9,13 @@ import (
"github.com/gobuffalo/buffalo/render"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
)
func NewContext(r Route, res http.ResponseWriter, req *http.Request, env string) *DefaultContext {
func newContext(r Route, res http.ResponseWriter, req *http.Request) *DefaultContext {
data := make(map[string]interface{})
data["path"] = r.Path
data["env"] = env
data["env"] = r.Env
params := req.URL.Query()
vars := mux.Vars(req)
@@ -27,7 +28,7 @@ func NewContext(r Route, res http.ResponseWriter, req *http.Request, env string)
request: req,
params: params,
data: data,
env: env,
env: r.Env,
}
}
@@ -39,6 +40,7 @@ type DefaultContext struct {
contentType string
data map[string]interface{}
env string
logger *logrus.Logger
}
// Response returns the original Response for the request.
@@ -118,3 +120,7 @@ func (d *DefaultContext) Redirect(status int, url string) error {
func (d *DefaultContext) Env() string {
return d.env
}
func (d *DefaultContext) Logger() *logrus.Logger {
return d.logger
}

View File

@@ -6,24 +6,20 @@ import (
"strings"
)
func NewRouter() Router {
return &DefaultRouter{}
func NewRouter(opts ...RouterOption) Router {
router := &DefaultRouter{}
router.Options = &RouterOptions{}
for _, opt := range opts {
opt(router.Options)
}
return router
}
type DefaultRouter struct {
Routes []*Route
StaticRoutes []*StaticRoute
prefix string
env string
}
func (r *DefaultRouter) Prefix(path string) {
r.prefix = path
}
func (r *DefaultRouter) SetEnv(env string) {
r.env = env
Options *RouterOptions
}
func (r *DefaultRouter) GET(path string, h Handler) {
@@ -53,15 +49,45 @@ func (r *DefaultRouter) GetStaticRoutes() []*StaticRoute {
return r.StaticRoutes
}
func (r *DefaultRouter) GetOptions() *RouterOptions {
return r.Options
}
func (r *DefaultRouter) addRoute(m, p string, h Handler) {
if r.prefix != "" {
p = fmt.Sprintf("/%s/%s", strings.Trim(r.prefix, "/"), strings.Trim(p, "/"))
if r.Options.Prefix != "" {
p = fmt.Sprintf("/%s/%s", strings.Trim(r.Options.Prefix, "/"), strings.Trim(p, "/"))
}
r.Routes = append(r.Routes, &Route{
Method: m,
Path: p,
Handler: h,
Env: r.env,
Env: r.Options.Env,
})
}
type RouterOptions struct {
Env string
Prefix string
MiddlewareStack MiddlewareStack
}
type RouterOption func(*RouterOptions)
func RouterEnv(env string) RouterOption {
return func(o *RouterOptions) {
o.Env = env
}
}
func RouterPrefix(p string) RouterOption {
return func(o *RouterOptions) {
o.Prefix = p
}
}
func RouterMiddleware(ms MiddlewareStack) RouterOption {
return func(o *RouterOptions) {
o.MiddlewareStack = ms
}
}

View File

@@ -37,8 +37,7 @@ func Test_Static_Route_Creation(t *testing.T) {
func Test_Prefix_Route_Creation(t *testing.T) {
r := require.New(t)
router := tuu.NewRouter()
router.Prefix("/prefix/")
router := tuu.NewRouter(tuu.RouterPrefix("/prefix"))
router.GET("/home", func(ctx tuu.Context) error { return nil })
router.GET("/home/about-us/", func(ctx tuu.Context) error { return nil })

View File

@@ -11,8 +11,7 @@ func main() {
// The render we currently use is the one built by gobuffalo.
r := render.New(render.Options{})
router := tuu.NewRouter()
router.SetEnv("dev")
router := tuu.NewRouter(tuu.RouterEnv("env"))
router.GET("/home", func(ctx tuu.Context) error {
ctx.Set("template_data", "some value")
@@ -28,13 +27,12 @@ func main() {
return nil
})
app := tuu.New(router)
err := app.Serve(tuu.Config{
app := tuu.New(router, tuu.Config{
IPAddr: "127.0.0.1",
Port: "8080",
Env: "dev",
}
})
err := app.Serve()
if err != nil {
panic(err)
}

28
middleware.go Normal file
View File

@@ -0,0 +1,28 @@
package tuu
type Middleware func(Handler) Handler
type MiddlewareStack struct {
stack []Middleware
}
func (m *MiddlewareStack) Use(mw ...Middleware) {
m.stack = append(m.stack, mw...)
}
func (m *MiddlewareStack) Get() []Middleware {
return m.stack
}
func (m *MiddlewareStack) handler(r *Route) Handler {
handler := r.Handler
if len(m.stack) == 0 {
return handler
}
for _, mw := range m.stack {
handler = mw(handler)
}
return handler
}

12
middleware/logger.go Normal file
View File

@@ -0,0 +1,12 @@
package middleware
import "github.com/lukerodham/tuu"
// RequestLogger is a default/example implementation of how a logging middleware would be implemented.
func RequestLogger(next tuu.Handler) tuu.Handler {
return func(c tuu.Context) error {
c.Logger().WithField("url", c.Value("path")).Debug("New request")
return next(c)
}
}

View File

@@ -3,8 +3,6 @@ package tuu
import (
"net/http"
"github.com/gorilla/mux"
gcontext "github.com/gorilla/context"
)
@@ -12,16 +10,18 @@ type Route struct {
Method string
Path string
Handler Handler
MuxHandler mux.Route
Env string
Middleware MiddlewareStack
}
func (r *Route) ServeHTTP(res http.ResponseWriter, req *http.Request) {
defer gcontext.Clear(req)
c := NewContext(*r, res, req, r.Env)
c := newContext(*r, res, req)
if err := r.Handler(c); err != nil {
err := r.Middleware.handler(r)(c)
if err != nil {
c.Response().WriteHeader(500)
c.Response().Write([]byte(err.Error()))
}

View File

@@ -5,9 +5,6 @@ import "net/http"
type Handler func(Context) error
type Router interface {
Prefix(path string)
SetEnv(env string)
GET(path string, h Handler)
POST(path string, h Handler)
Static(path string, root http.FileSystem)
@@ -15,4 +12,5 @@ type Router interface {
GetRoutes() []*Route
GetStaticRoutes() []*StaticRoute
GetOptions() *RouterOptions
}

11
tuu.go
View File

@@ -17,16 +17,17 @@ type Config struct {
Env string
}
func New(r Router) *App {
return &App{router: r}
func New(r Router, cfg Config) *App {
return &App{router: r, cfg: cfg}
}
type App struct {
router Router
cfg Config
}
func (a *App) Serve(cfg Config) error {
log.Printf("http server running @ http://%s:%s", cfg.IPAddr, cfg.Port)
func (a *App) Serve() error {
log.Printf("http server running @ http://%s:%s", a.cfg.IPAddr, a.cfg.Port)
r := mux.NewRouter()
@@ -39,7 +40,7 @@ func (a *App) Serve(cfg Config) error {
}
server := http.Server{
Addr: fmt.Sprintf("%s:%s", cfg.IPAddr, cfg.Port),
Addr: fmt.Sprintf("%s:%s", a.cfg.IPAddr, a.cfg.Port),
Handler: r,
}