Golang Web Mvc Framework
Routes map incoming requests for URLs to a Controller and Action. They also are used to construct an URL to a Controller/Action.
You can map route by this two ways:
var Routes []*goku.Route = []*goku.Route{
&goku.Route{
Name: "static",
IsStatic: true,
Pattern: "/public/(.*)",
},
&goku.Route{
Name: "edit",
Pattern: "/{controller}/{id}/{action}",
Default: map[string]string{"action": "edit"},
Constraint: map[string]string{"id": "\\d+"},
},
&goku.Route{
Name: "default",
Pattern: "/{controller}/{action}",
Default: map[string]string{"controller": "todo", "action": "index"},
},
}
// create server with the rules
rt := &goku.RouteTable{Routes: todo.Routes}
s := goku.CreateServer(rt, nil, nil)
log.Fatal(s.ListenAndServe())
or
rt := new(goku.RouteTable)
rt.Static("staticFile", "/static/(.*)")
rt.Map(
"blog-page", // route name
"/blog/p/{page}", // pattern
map[string]string{"controller": "blog", "action": "page", "page": "0"}, // default
map[string]string{"page": "\\d+"} // constraint
)
rt.Map(
"default", // route name
"/{controller}/{action}", // pattern
map[string]string{"controller": "home", "action": "index"}, // default
)
When a route set IsStatic
to true
, if a url matched this route, the request will process as static file. Such as JS, CSS file.
In production environment, i suggest you proxy the static files with Nginx.
A URL pattern can contain literal values and variable placeholders (referred to as URL parameters). The literals and placeholders are located in segments of the URL which are delimited by the slash (/) character.
When a request is made, the URL is parsed into segments and placeholders, and the variable values are provided to the request handler. This process is similar to the way the data in query strings is parsed and passed to the request handler. In both cases variable information is included in the URL and passed to the handler in the form of key-value pairs. For query strings both the keys and the values are in the URL. For routes, the keys are the placeholder names defined in the URL pattern, and only the values are in the URL.
In a URL pattern, you define placeholders by enclosing them in braces ( { and } ). You can define more than one placeholder in a segment, but they must be separated by a literal value. For example, {language}-{country}/{action}
is a valid route pattern. However, {language}{country}/{action}
is not a valid pattern, because there is no literal value or delimiter between the placeholders. Therefore, routing cannot determine where to separate the value for the language placeholder from the value for the country placeholder.
The following table shows valid route patterns and examples of URL requests that match the patterns.
Route definition | Example of matching URL |
---|---|
{controller}/{action}/{id} | /Products/show/beverages |
{table}/Details.html | /Products/Details.html |
blog/{action}/{entry} | /blog/show/123 |
{reporttype}/{year}/{month}/{day} | /sales/2008/1/5 |
{locale}/{action} | /US/show |
{language}-{country}/{action} | /en-US/show |
When you define a route, you can assign a default value for a parameter. The default value is used if a value for that parameter is not included in the URL. You set default values for a route by assigning a map to the Defaults
property of the Route
struct. The following example shows how to add a route that has default values, by using the MapPageRoute(String, String, String, Boolean, RouteValueDictionary) method.
var Routes []*goku.Route = []*goku.Route{
&goku.Route{
Name: "default",
Pattern: "Category/{action}/{categoryName}",
Default: map[string]string{
"controller": "category", "action": "show", "categoryName":"food"
},
}
}
When goku routing handles a URL request, the route definition shown in the example (with default values of food for categoryName and show for action) produces the results that are listed in the following table.
URL | Parameter values |
---|---|
/Category | action = “show” (default value) categoryName = “food” (default value) |
/Category/add | action = “add” categoryName = “food” (default value) |
/Category/add/beverages | action = “add” categoryName= “beverages” |
In addition to matching a URL request to a route definition by the number of parameters in the URL, you can specify that values in the parameters meet certain constraints. If a URL contains values that are outside the constraints for a route, that route is not used to handle the request. You add constraints to make sure that the URL parameters contain values that will work in your application.
Constraints are defined by using regular expressions. You add constraints for a route by assigning a map to the Constraint
property of the Route
struct, or add by RouteTable.Map()
var Routes []*goku.Route = []*goku.Route{
&goku.Route{
Name: "post-list",
Pattern: "whatever/{locale}/{year}",
Constraint: map[string]string{
"locale": "[a-z]{2}-[a-z]{2}", "year": "\\d{4}"
},
},
}
// or
rt := new(goku.RouteTable)
rt.Map(
"post-list", // route name
"whatever/{locale}/{year}", // pattern
map[string]string{"controller": "post", "action": "show"}, // default
map[string]string{ // constraint
"locale": "[a-z]{2}-[a-z]{2}", "year": "\\d{4}"
}
)
When routing handles a URL request, the route definition shown in the previous example produces the results that are listed in the following table.
URL | Result |
---|---|
/en-us | No match. Both locale and year are required. |
/en-us/08 | No match. The constraint on year requires 4 digits. |
/en-us/2008 | locale = “en-us” year = “2008” |
If default value not set, that mean the parameter is required.
For the Pattern Category/{action}/{categoryName}
, and a URL /Category/add/beverages
, you can get the categoryName
parameter in the controller action by HttpContext:
// ctx is HttpContext
categoryName := ctx.RouteData.Params["categoryName"]
// categoryName == beverages