Routing

    Basic Routes

    Routes are defined by specifying a URI pattern and Callback to the router.

    // Respond with "Hello World!" to GET request with the path /hi
    router.Get("/hi", func(res h.Response) h.Result {
        return res.Data("Hello World!")
    })
    

    All common HTTP verbs have a corresponding method.

    r.Get(uri string, callback h.Callback)
    r.Post(uri string, callback h.Callback)
    r.Put(uri string, callback h.Callback)
    r.Patch(uri string, callback h.Callback)
    r.Delete(uri string, callback h.Callback)
    
    // Even less common verbs
    r.Options(uri string, callback h.Callback)
    r.Head(uri string, callback h.Callback)
    r.Connect(uri string, callback h.Callback)
    r.Trace(uri string, callback h.Callback)
    

    There is also a Match method to match multiple HTTP verbs, and an Any method to match all HTTP verbs.

    r.Match([]string{"GET", "CUSTOM"}, "/", func(res h.Response) h.Result {
    	// ...
    })
    
    r.Any("/", func(res h.Response) h.Result { 
    	// ...
    })
    

    Callback Function

    The second argument to create a route is the Callback, which is called whenever an HTTP request is received that matches the URI pattern. Callback can receive any arguments, that can be resolved by the IoC container.

    For example, you can access settings from the Config object.

    r.Get("/", func(res h.Response, c *hemlock.Config) h.Result {
        return res.Data("Running on port: "+c.HTTP.Port)
    })
    

    Or access user input from the request.

    r.Get("/", func(res h.Response, req h.Request) h.Result {
        return res.Dataf("Query param foo: "+req.Query("foo"))
    })
    

    Redirects

    For simple redirects, the Redirect method can be used to redirect the client to another URI.

    r.Redirect("/old/page", "/new/page", 302)
    

    Views

    A view can also be

    r.View("/", "home.html", "base.html", )
    

    Route Parameters

    Basic URL parameters can be added using the {name} notation. These parameters can be accessed by specifying them as arguments at the end of the Callback.

    Any route parameters are appended to the Callback arguments when the route is invoked.

    r.Get(
    	"/hi/{name}/{message}", 
    	func(res h.Response, name, message string) h.Result {
            return res.Dataf("Hi %s! %s.", name, message)
        },
    )
    

    Regular Expression

    Patterns can also contain a regular expression.

    Here is an example that uses a regular expression pattern to differentiate numerical user IDs from usernames.

    r.Get("/users/{id:[0-9]+}", useByID) // Only match numbers
    r.Get("/users/{id}", userByUsername) // Match everything else
    

    Middleware

    Both the Use and With method can be used to assign middleware.

    The Use method applies middleware directly to the router or route reference.

    r.Use(func(req h.Request, res h.Response, next h.Next) h.Result {
    	// ... 
    }
    

    The With method is similar to Use but creates a new router instance with the applied middleware.

    r.With(adminMiddleware).Get("/admin/dashboard", adminPanel)
    

    Named Routes

    Routes can be assigned names which can be used to reference them later on.

    r.Get("/users", listUsers).Name("users.list")
    r.Get("/users/{id}", showUser).Name("users.show")
    

    For example, a URL can be constructed for named routes.

    <a href="{{ route "users.list" }}">
        List Users
    </a>
    
    <a href="{{ route "users.show" "id" "123" }}">
        Show User
    </a>
    

    Requests can also be redirected to named routes.

    r.Get("/account", func(res h.Response) h.Result {
        return res.RedirectRoute("users.list", nil)
    )
    
    r.Get("/accounts/{id}", func(res h.Response, id string) h.Result {
        return res.RedirectRoute("users.show", map[string]string{"id": id})
    )
    

    Grouping Routes

    The Group method creates a new child router instance. All routes defined on the new router will have the previous filters applied.

    r.Host("admin.gohemlock.com").Prefix("/admin").Group(func(r h.Router) {
    	r.Use(adminMiddleware)              
        r.Get("/dashboard", adminPanel)        // [GET] /admin/panel
        r.Put("/revoke/{username}", adminBan)  // [PUT] /admin/revoke/gschier
    })
    

    RESTful Routes

    The Group method is useful for combining routes related to the same resource.

    r.Prefix("/tasks").Group(func(r h.Router) {
    	r.Use(authedMiddleware)
        r.Get("/", users.List)      // [GET]  /tasks
        r.Post("/", users.Create)   // [POST] /tasks
        r.Prefix("/{id}").Group(func(r h.Router) {
            r.Get("/", users.Show)        // [GET]    /tasks/gschier
            r.Delete("/", users.Delete)   // [DELETE] /tasks/gschier
            r.Patch("/", users.Update)    // [PATCH]  /tasks/gschier
        })
    })
    

    Advanced Usage

    There are a few more methods that offer precise control over route creation.

    Use Callback to match any URI on the current router which most commonly paired with the Prefix method.

    r.Prefix("/docs").Callback(serveMarkdown)
    

    Methods also adds an additional level of control.

    r.Methods("GET", "HEAD").Prefix("/docs").Callback(serveMarkdown)
    
    // Or a more realistic advanced example...
    r.Prefix("/docs").Methods("GET", "HEAD").Group(func(r h.Router) {
    	r.Use(adminOnlyMiddleware)
    	r.Use(cachedMiddleware)
    	
    	// Use `Callback` to match any route within the route group
    	// [GET]  /docs
    	// [HEAD] /docs/foo.md
    	// [GET]  /docs/foo/bar.md
    	// ...
    	r.Callback(serveMarkdown)
    })