github.com/lenfree/buffalo@v0.7.3-0.20170207163156-891616ea4064/router.go (about) 1 package buffalo 2 3 import ( 4 "fmt" 5 "net/http" 6 "path" 7 "path/filepath" 8 "sort" 9 10 "github.com/markbates/inflect" 11 ) 12 13 // GET maps an HTTP "GET" request to the path and the specified handler. 14 func (a *App) GET(p string, h Handler) RouteInfo { 15 return a.addRoute("GET", p, h) 16 } 17 18 // POST maps an HTTP "POST" request to the path and the specified handler. 19 func (a *App) POST(p string, h Handler) RouteInfo { 20 return a.addRoute("POST", p, h) 21 } 22 23 // PUT maps an HTTP "PUT" request to the path and the specified handler. 24 func (a *App) PUT(p string, h Handler) RouteInfo { 25 return a.addRoute("PUT", p, h) 26 } 27 28 // DELETE maps an HTTP "DELETE" request to the path and the specified handler. 29 func (a *App) DELETE(p string, h Handler) RouteInfo { 30 return a.addRoute("DELETE", p, h) 31 } 32 33 // HEAD maps an HTTP "HEAD" request to the path and the specified handler. 34 func (a *App) HEAD(p string, h Handler) RouteInfo { 35 return a.addRoute("HEAD", p, h) 36 } 37 38 // OPTIONS maps an HTTP "OPTIONS" request to the path and the specified handler. 39 func (a *App) OPTIONS(p string, h Handler) RouteInfo { 40 return a.addRoute("OPTIONS", p, h) 41 } 42 43 // PATCH maps an HTTP "PATCH" request to the path and the specified handler. 44 func (a *App) PATCH(p string, h Handler) RouteInfo { 45 return a.addRoute("PATCH", p, h) 46 } 47 48 // ServeFiles maps an path to a directory on disk to serve static files. 49 // Useful for JavaScript, images, CSS, etc... 50 /* 51 a.ServeFiles("/assets", http.Dir("path/to/assets")) 52 */ 53 func (a *App) ServeFiles(p string, root http.FileSystem) { 54 a.router.PathPrefix(p).Handler(http.StripPrefix(p, http.FileServer(root))) 55 } 56 57 // Resource maps an implementation of the Resource interface 58 // to the appropriate RESTful mappings. Resource returns the *App 59 // associated with this group of mappings so you can set middleware, etc... 60 // on that group, just as if you had used the a.Group functionality. 61 /* 62 a.Resource("/users", &UsersResource{}) 63 64 // Is equal to this: 65 66 ur := &UsersResource{} 67 g := a.Group("/users") 68 g.GET("/", ur.List) // GET /users => ur.List 69 g.GET("/new", ur.New) // GET /users/new => ur.New 70 g.GET("/{user_id}", ur.Show) // GET /users/{user_id} => ur.Show 71 g.GET("/{user_id}/edit", ur.Edit) // GET /users/{user_id}/edit => ur.Edit 72 g.POST("/", ur.Create) // POST /users => ur.Create 73 g.PUT("/{user_id}", ur.Update) PUT /users/{user_id} => ur.Update 74 g.DELETE("/{user_id}", ur.Destroy) DELETE /users/{user_id} => ur.Destroy 75 */ 76 func (a *App) Resource(p string, r Resource) *App { 77 base := filepath.Base(p) 78 single := inflect.Singularize(base) 79 g := a.Group(p) 80 p = "/" 81 spath := filepath.Join(p, fmt.Sprintf("{%s_id}", single)) 82 g.GET(p, r.List) 83 g.GET(filepath.Join(p, "new"), r.New) 84 g.GET(filepath.Join(spath), r.Show) 85 g.GET(filepath.Join(spath, "edit"), r.Edit) 86 g.POST(p, r.Create) 87 g.PUT(filepath.Join(spath), r.Update) 88 g.DELETE(filepath.Join(spath), r.Destroy) 89 return g 90 } 91 92 // ANY accepts a request across any HTTP method for the specified path 93 // and routes it to the specified Handler. 94 func (a *App) ANY(p string, h Handler) { 95 a.GET(p, h) 96 a.POST(p, h) 97 a.PUT(p, h) 98 a.PATCH(p, h) 99 a.HEAD(p, h) 100 a.OPTIONS(p, h) 101 a.DELETE(p, h) 102 } 103 104 // Group creates a new `*App` that inherits from it's parent `*App`. 105 // This is useful for creating groups of end-points that need to share 106 // common functionality, like middleware. 107 /* 108 g := a.Group("/api/v1") 109 g.Use(AuthorizeAPIMiddleware) 110 g.GET("/users, APIUsersHandler) 111 g.GET("/users/:user_id, APIUserShowHandler) 112 */ 113 func (a *App) Group(path string) *App { 114 g := New(a.Options) 115 g.prefix = filepath.Join(a.prefix, path) 116 g.router = a.router 117 g.Middleware = a.Middleware.clone() 118 g.root = a 119 if a.root != nil { 120 g.root = a.root 121 } 122 return g 123 } 124 125 func (a *App) addRoute(method string, url string, h Handler) RouteInfo { 126 a.moot.Lock() 127 defer a.moot.Unlock() 128 129 url = path.Join(a.prefix, url) 130 hs := funcKey(h) 131 r := RouteInfo{ 132 Method: method, 133 Path: url, 134 HandlerName: hs, 135 Handler: h, 136 } 137 138 r.MuxRoute = a.router.Handle(url, a.handlerToHandler(r, h)).Methods(method) 139 140 routes := a.Routes() 141 routes = append(routes, r) 142 sort.Sort(routes) 143 if a.root != nil { 144 a.root.routes = routes 145 } else { 146 a.routes = routes 147 } 148 149 return r 150 }