Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Revel routes routing


May 15, 2021 Revel


Table of contents


Routes are defined in a routes file.

The routing definition rules are:

(METHOD) (URL Pattern) (Controller.Action)

Here's a demonstration of the definition of routing:

# conf/routes
# 这个文件定义了应用程序的所有路由 (优先级按照先后顺序)
GET    /login                 App.Login              # 一个简单的路由
GET    /hotels/               Hotels.Index           # 一个简单的路由,带不带斜线后缀都一样
GET    /hotels/:id            Hotels.Show            # 绑定到一个URI参数id
WS     /hotels/:id/feed       Hotels.Feed            # WebSockets
POST   /hotels/:id/:action    Hotels.:action         # 自动匹配路由到一个控制器的多个方法
GET    /public/*filepath      Static.Serve("public") # 映射到 /public/下的静态文件
  • /: controller/: action :controller.: action s capture all controller methods; The URL is automatically generated

Let's look at it one by one. Finally, let's look at how to implement inverse routing - generating a URL to call a particular method

A simple route

GET    /login                 App.Login

Match a URL directly to a controller method.

Slash suffix

GET    /hotels/               Hotels.Index

/hotels /hotels/ call the Hotels.Index method. Reversing Hotels.Index will contain a slash suffix.

Slash suffixes cannot be used to distinguish between two routes with the /login /login/ the same

URL parameters

GET    /hotels/:id            Hotels.Show

Revel can re-extract parameters from the URL and bind them to the controller method. :id variable attempts to match any value except the slash suffix. To name a /hotels/123 /hotels/abc all match this route.

The extracted parameters are Controller.Params map, bound to the controller method Show. Take a chestnut:

func (c Hotels) Show(id int) revel.Result {
    ...
}

Or

func (c Hotels) Show() revel.Result {
    var id string = c.Params.Get("id")
    ...
}

Or

func (c Hotels) Show() revel.Result {
    var id int
    c.Params.Bind(&id, "id")
    ...
}

Wildcard

GET    /public/*filepath            Static.Serve("public")

The router recognizes the second wildcard. Wildcards must be placed in front of the last element of the route, matching all URLs that begin with the path before

The route here will match "/public/" and all paths that begin with him

Websockets

WS     /hotels/:id/feed       Hotels.Feed

Websockets accepts requests in the same way, using the WS identifier

The corresponding method signature is as follows:

func (c Hotels) Feed(ws *websocket.Conn, id int) revel.Result {
    ...
}

Static file service

GET    /public/*filepath            Static.Serve("public")
GET    /favicon.ico                 Static.Serve("public","img/favicon.png")

For Static.Serve, which uses 2 , parameters, spaces are not allowed between " and , due to how encoding/csv works.

For static resource services, Revel is supported by a static module that contains a single static controller with two parameters

  • Prefix (string) - specifies a relative or absolute path to the static file root
  • File Path (String) - Specifies the relative path of the file.

(You can refer to the code structure layout for more information)

Fixed parameters

Routes can bind one or more parameters to the controller method, to name a chestnut:

GET    /products/:id     ShowList("PRODUCT")
GET    /menus/:id        ShowList("MENU")

The argument is bound to the argument name by its position in the route, and here the string in the list is bound to the first argument of the method.

Here are a few useful scenarios:

  • A method of a similar set of functions
  • The same functionality works in different modes
  • The same functional method, but operates on different data types

Automatic routing

POST   /hotels/:id/:action    Hotels.:action
  • /:controller/:action :controller.:action

Extracts of URLs can also be used to determine which controller method to call. Match rules are case insenso sensitive

The first example matches the route below

/hotels/1/show    => Hotels.Show
/hotels/2/details => Hotels.Details

The second example matches any method in the application

/app/login         => App.Login
/users/list        => Users.List

Because matching controllers and methods are case insensescies, the following routes also match

/APP/LOGIN         => App.Login
/Users/List        => Users.List

Using automatic routing as a way to capture all, such as the last route in a file, for a quick hook method, to non-vanity URLs, especially when used with reverse routers, is useful.

Reverse the route

Using inverse routing to generate URLs is a good way to do this in the following cases.

  • Avoid spelling mistakes
  • The compiler ensures that the reverse route has the correct number and parameter type.
  • The route needs to be modified only once in the routings file

When building a program, Revel automatically generates a app/routes which can be used by a single statement:

routes.Controller.Action(param1, param2)

The above statement returns a string-type URL using Controller.Action and parameters, and here's a complete example:

import (
    "github.com/revel/revel"
    "project/app/routes"
)

type App struct { *revel.Controller }

// 生成一个表单页面
func (c App) ViewForm(username string) revel.Result {
    return c.Render(username)
}

// 处理提交的表单
func (c App) ProcessForm(username, input string) revel.Result {
    ...
    if c.Validation.HasErrors() {
        c.Validation.Keep()
        c.Flash.Error("Form invalid. Try again.")
        return c.Redirect(routes.App.ViewForm(username))  // <--- 反转路由
    }
    c.Flash.Success("Form processed!")
    return c.Redirect(routes.App.ViewConfirmation(username, input))  // <--- 反转路由
}

Limitations: O nly primitive parameters to a route are typed due to the possibility of circular imports. Non-primitive parameters are typed as interface{}.