Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1502)

Side by Side Diff: server/router/router.go

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: Fixes to middleware append related functions, docs Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 /*
6 Package router provides a HTTP router with support for middleware and groups.
7 It wraps around julienschmidt/httprouter.
8
9 Usage:
10
11 r := router.Default()
12 r.UseHandlers(Logger())
13 r.GET("/", middleware.NewChain(RootSpecificMiddleware(), rootHandler)) / / Executes Logger, RootSpecificMiddleware, rootHandler in order
14
15 authorized := r.Group("authorized")
16 authorized.UseHandlers(Authenticator(), FooAuthMiddleware())
17 authorized.DELETE("/comment/:id", commentDeleteHandler) // Executes Logg er, Authenticator, FooAuthMiddleware, commentDeleteHandler in order (path: /auth orized/comment/:id)
18
19 func rootHandler(ctx context.Context, rw http.ResponseWriter, r *http.Re quest, p httprouter.Params, _ middleware.Handler) {
20 io.WriteString(rw, "hello from the root route")
21 }
22
23 func Logger() middleware.ChainedHandler {
24 return func(ctx context.Context, rw http.ResponseWriter, r *http .Request, p httprouter.Params, next middleware.Handler) {
25 log.Println("log before")
26 next(ctx, rw, r, p)
27 log.Println("log after")
28 }
29 }
30 */
31 package router
32
33 import (
34 "net/http"
35
36 "github.com/julienschmidt/httprouter"
37 "github.com/luci/luci-go/server/middleware"
38 "golang.org/x/net/context"
39 )
40
41 // Router represents the main router type.
42 type Router struct {
43 hrouter *httprouter.Router
44 context context.Context
45 handlers middleware.Chain
46 basePath string
47 parent *Router
48 root bool
49 }
50
51 var _ http.Handler = Default()
52
53 // Default creates a Router with context.Background() as initial context.
54 func Default() *Router {
55 return New(context.Background())
56 }
57
58 // New creates a Router with specified initial context.
59 func New(ctx context.Context) *Router {
60 r := &Router{
61 hrouter: httprouter.New(),
62 context: ctx,
63 basePath: "/",
64 parent: nil,
65 root: true,
66 }
67 return r
68 }
69
70 // UseHandlers adds handlers as middleware to the group. The added middleware ap plies to
71 // all routes in the current group and in groups derived from the current group.
72 func (r *Router) UseHandlers(handlers ...middleware.ChainedHandler) {
73 r.handlers = r.handlers.Append(middleware.NewChain(handlers...))
74 }
75
76 // Use adds middleware chains to the group. The added middleware applies to
77 // all routes in the current group and in groups derived from the current group.
78 func (r *Router) Use(chains ...middleware.Chain) {
79 r.handlers = r.handlers.Append(chains...)
80 }
81
82 // Group creates a new router with an updated base path.
83 // The new router carries over configuration from the router it derives
84 // from.
85 func (r *Router) Group(relativePath string) *Router {
86 return &Router{
87 hrouter: r.hrouter,
88 context: r.context,
89 handlers: r.handlers,
90 basePath: r.basePath + relativePath,
91 parent: r,
92 root: false,
93 }
94 }
95
96 // adapt converts a middleware.Chain to a httrouter.Handle with
97 // initial context.
98 func (r *Router) adapt(chain middleware.Chain) httprouter.Handle {
99 return httprouter.Handle(func(rw http.ResponseWriter, req *http.Request, p httprouter.Params) {
100 chain.Handle(r.context, rw, req, p)
101 })
102 }
103
104 // GET is a shortcut for router.Handle("GET", path, handlers)
105 func (r *Router) GET(path string, handlers middleware.Chain) {
106 r.Handle("GET", path, handlers)
107 }
108
109 // HEAD is a shortcut for router.Handle("HEAD", path, handlers)
110 func (r *Router) HEAD(path string, handlers middleware.Chain) {
111 r.Handle("HEAD", path, handlers)
112 }
113
114 // OPTIONS is a shortcut for router.Handle("OPTIONS", path, handlers)
115 func (r *Router) OPTIONS(path string, handlers middleware.Chain) {
116 r.Handle("OPTIONS", path, handlers)
117 }
118
119 // POST is a shortcut for router.Handle("POST", path, handlers)
120 func (r *Router) POST(path string, handlers middleware.Chain) {
121 r.Handle("POST", path, handlers)
122 }
123
124 // PUT is a shortcut for router.Handle("PUT", path, handlers)
125 func (r *Router) PUT(path string, handlers middleware.Chain) {
126 r.Handle("PUT", path, handlers)
127 }
128
129 // PATCH is a shortcut for router.Handle("PATCH", path, handlers)
130 func (r *Router) PATCH(path string, handlers middleware.Chain) {
131 r.Handle("PATCH", path, handlers)
132 }
133
134 // DELETE is a shortcut for router.Handle("DELETE", path, handlers)
135 func (r *Router) DELETE(path string, handlers middleware.Chain) {
136 r.Handle("DELETE", path, handlers)
137 }
138
139 // Handle registers a new middleware chain-style handler with the given method
140 // and path.
141 func (r *Router) Handle(method, path string, handlers middleware.Chain) {
142 mergedHandlers := r.handlers.Append(handlers)
143 h := r.adapt(mergedHandlers)
144 r.hrouter.Handle(method, path, h)
145 }
146
147 // ServeHTTP makes Router implement the http.Handler interface.
148 func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
149 r.hrouter.ServeHTTP(rw, req)
150 }
151
152 // TODO(nishanths): implement Handler, HandlerFunc adapter methods on *Router
OLDNEW
« server/middleware/middleware.go ('K') | « server/middleware/middleware.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698