github.com/ashleymcnamara/buffalo@v0.8.0/router.go (about)

     1  package buffalo
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"path"
     7  	"sort"
     8  	//"strings"
     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  // Redirect from one URL to another URL. Only works for "GET" requests.
    49  func (a *App) Redirect(status int, from, to string) RouteInfo {
    50  	return a.GET(from, func(c Context) error {
    51  		return c.Redirect(status, to)
    52  	})
    53  }
    54  
    55  // ServeFiles maps an path to a directory on disk to serve static files.
    56  // Useful for JavaScript, images, CSS, etc...
    57  /*
    58  	a.ServeFiles("/assets", http.Dir("path/to/assets"))
    59  */
    60  func (a *App) ServeFiles(p string, root http.FileSystem) {
    61  	a.router.PathPrefix(p).Handler(http.StripPrefix(p, http.FileServer(root)))
    62  }
    63  
    64  // Resource maps an implementation of the Resource interface
    65  // to the appropriate RESTful mappings. Resource returns the *App
    66  // associated with this group of mappings so you can set middleware, etc...
    67  // on that group, just as if you had used the a.Group functionality.
    68  /*
    69  	a.Resource("/users", &UsersResource{})
    70  
    71  	// Is equal to this:
    72  
    73  	ur := &UsersResource{}
    74  	g := a.Group("/users")
    75  	g.GET("/", ur.List) // GET /users => ur.List
    76  	g.GET("/new", ur.New) // GET /users/new => ur.New
    77  	g.GET("/{user_id}", ur.Show) // GET /users/{user_id} => ur.Show
    78  	g.GET("/{user_id}/edit", ur.Edit) // GET /users/{user_id}/edit => ur.Edit
    79  	g.POST("/", ur.Create) // POST /users => ur.Create
    80  	g.PUT("/{user_id}", ur.Update) PUT /users/{user_id} => ur.Update
    81  	g.DELETE("/{user_id}", ur.Destroy) DELETE /users/{user_id} => ur.Destroy
    82  */
    83  func (a *App) Resource(p string, r Resource) *App {
    84  	base := path.Base(p)
    85  	single := inflect.Singularize(base)
    86  	g := a.Group(p)
    87  	p = "/"
    88  	spath := path.Join(p, fmt.Sprintf("{%s_id}", single))
    89  	g.GET(p, r.List)
    90  	g.GET(path.Join(p, "new"), r.New)
    91  	g.GET(path.Join(spath), r.Show)
    92  	g.GET(path.Join(spath, "edit"), r.Edit)
    93  	g.POST(p, r.Create)
    94  	g.PUT(path.Join(spath), r.Update)
    95  	g.DELETE(path.Join(spath), r.Destroy)
    96  	return g
    97  }
    98  
    99  // ANY accepts a request across any HTTP method for the specified path
   100  // and routes it to the specified Handler.
   101  func (a *App) ANY(p string, h Handler) {
   102  	a.GET(p, h)
   103  	a.POST(p, h)
   104  	a.PUT(p, h)
   105  	a.PATCH(p, h)
   106  	a.HEAD(p, h)
   107  	a.OPTIONS(p, h)
   108  	a.DELETE(p, h)
   109  }
   110  
   111  // Group creates a new `*App` that inherits from it's parent `*App`.
   112  // This is useful for creating groups of end-points that need to share
   113  // common functionality, like middleware.
   114  /*
   115  	g := a.Group("/api/v1")
   116  	g.Use(AuthorizeAPIMiddleware)
   117  	g.GET("/users, APIUsersHandler)
   118  	g.GET("/users/:user_id, APIUserShowHandler)
   119  */
   120  func (a *App) Group(groupPath string) *App {
   121  	g := New(a.Options)
   122  
   123  	g.prefix = path.Join(a.prefix, groupPath)
   124  
   125  	g.router = a.router
   126  	g.Middleware = a.Middleware.clone()
   127  	g.ErrorHandlers = a.ErrorHandlers
   128  	g.root = a
   129  	if a.root != nil {
   130  		g.root = a.root
   131  	}
   132  	return g
   133  }
   134  
   135  func (a *App) addRoute(method string, url string, h Handler) RouteInfo {
   136  	a.moot.Lock()
   137  	defer a.moot.Unlock()
   138  
   139  	url = path.Join(a.prefix, url)
   140  
   141  	hs := funcKey(h)
   142  	r := RouteInfo{
   143  		Method:      method,
   144  		Path:        url,
   145  		HandlerName: hs,
   146  		Handler:     h,
   147  	}
   148  
   149  	r.MuxRoute = a.router.Handle(url, a.handlerToHandler(r, h)).Methods(method)
   150  
   151  	routes := a.Routes()
   152  	routes = append(routes, r)
   153  	sort.Sort(routes)
   154  	if a.root != nil {
   155  		a.root.routes = routes
   156  	} else {
   157  		a.routes = routes
   158  	}
   159  
   160  	return r
   161  }