Erlang cowboy routing 路由

本文译自:

http://ninenines.eu/docs/en/cowboy/1.0/guide/routing/

Routing

默认情况下,Cowboy 什么都不做。

所谓路由(routing),就是把URL请求映射到Erlang处理模块。一旦Cowboy收到一个请求,它会按指定的规则匹配请求的host和path,如果匹配成功,关联的模块代码就被执行。路由规则按每个host指定,Cowboy首先匹配host,然后匹配path,...

路由表在使用前需要先编译。

Structure

路由表的结构如下:

Routes = [Host1, Host2, ... HostN].

表中的每一项是一个host,host包含路径列表(pathlist),host的结构如下:

Host1 = {HostMatch, PathsList}.
Host2 = {HostMatch, Constraints, PathsList}.

类似的,pathlist的结构如下:

PathsList = [Path1, Path2, ... PathN].

每个path包含可选的匹配条件,处理器,和选项,定义如下:

Path1 = {PathMatch, Handler, Opts}.
Path2 = {PathMatch, Constraints, Handler, Opts}.

下面看看可选的匹配条件的语法match syntax。

Match syntax

匹配语法用于关联路径到各自的处理模块handler。

匹配语法同样适用于host和path,差别不大。实际上,段的分隔符不同,host从最后一个段向第一个段匹配。下面在遇到的时候会详细说明host和path的匹配不同之处。

除了本节最后我会说明的一些特殊情况,最简单的匹配值就是host和path,通过string() 或  binary()指定。

PathMatch1 = "/".
PathMatch2 = "/path/to/resource".

HostMatch1 = "cowboy.example.org".

可见,所有的路径都是以斜杠"/"开头。下面2种写法是等效的:

PathMatch2 = "/path/to/resource".
PathMatch3 = "/path/to/resource/".

Host结尾和开头有没有一个点"."都可以,下面3个都是等价的:

HostMatch1 = "cowboy.example.org".
HostMatch2 = "cowboy.example.org.".
HostMatch3 = ".cowboy.example.org".

从host和path中提取的段值会保存在Req对象里以待后用。我们称其为绑定(从URL提取段值存储于指定变量的过程)。

绑定的语法很简单。以冒号":"开头的名称都是绑定变量名,值就是段:

PathMatch = "/hats/:name/prices".
HostMatch = ":subdomain.example.org".

对于上面的例子,URL http://test.example.org/hats/wild_cowboy_legendary/prices 绑定之后得到的变量是:

subdomain=test

name=wild_cowboy_legendary

变量subdomain和name随后用cowboy_req:binding/{2,3}函数取得,绑定的变量名必须是atom类型。

一种特殊的绑定变量名是冒号加下划线":_"。匹配的段值会忽略。这种方式在匹配多域名时很有用。

HostMatch = "ninenines.:_".

还可以匹配可选的段。方括号内的都是可选的匹配。

PathMatch = "/hats/[page/:number]".
HostMatch = "[www.]ninenines.eu".

还可以嵌套:

PathMatch = "/hats/[page/[:number]]".

还可以用[...]匹配host和path其余的部分。在host中匹配前面的部分,在path中匹配后面的部分。匹配的结果可以有0,1或多个段。用cowboy_req:host_info/1cowboy_req:path_info/1分布取得这些段值,以列表形式返回。

PathMatch = "/hats/[...]".
HostMatch = "[...]ninenines.eu".

如果同一个绑定变量名出现2次,只有当它们的值一致时,匹配才算成功。这源自于Erlang模式匹配的方式。

PathMatch = "/hats/:name/:name".

当相同变量出现在可选段的匹配中,只有当可选的段存在,并且2个值一致时:

This is also true when an optional segment is present. In this case the two values must be identical only if the segment is available.

PathMatch = "/hats/:name/[:name]".

如果一个绑定变量在host和path中都存在,那么他们的值必须一致才算成功:

PathMatch = "/:user/[...]".
HostMatch = ":user.github.com".

最后是2个特殊匹配。原子'_'用于匹配任何host和path。

PathMatch = '_'.
HostMatch = '_'.

host的匹配"*"匹配通配符path,通常与OPTIONS方法一起使用。

HostMatch = "*".

Constraints

当匹配结束,绑定的结果就要经过一组条件测试。条件测试仅当绑定被定义。运行的次序就是你定义他们的次序。匹配最终成功仅当满足所有条件。

条件是2个或3个元素的元组形式,第一个元素是绑定的变量名称,第二个元素是条件名称,第三个元素是可选的参数,存放条件的参数。下面条件的定义:

  • {Name, int}
  • {Name, function, fun ((Value) -> true | {true, NewValue} | false)}

int 条件会检查绑定变量Name存放的值是一个整数字串(Name="123"),如果是,转换值到整数(Name=123)。

function条件传递绑定的值到一个用户定义的函数, 它会取得这个绑定的变量的值作为它的唯一参数,并且必须返回是否满足条件。也可以在函数中修改这个值,因此这个值可以返回任何类型。

注意,条件函数应该是简单不能出错:Note that constraint functions SHOULD be pure and MUST NOT crash.

Compilation

本章定义的结构在传递给Cowboy使用前需要编译。这样会提高速度。编译使用:

cowboy_router:compile/1.

Dispatch = cowboy_router:compile([
    %% {HostMatch, list({PathMatch, Handler, Opts})}
    {'_', [{'_', my_handler, []}]}
]),
%% Name, NbAcceptors, TransOpts, ProtoOpts
cowboy:start_http(my_http_listener, 100,
    [{port, 8080}],
    [{env, [{dispatch, Dispatch}]}]
).

如果给定的结构不正确,函数会返回{error, badarg}

动态替换

使用 cowboy:set_env/3 函数更新路由策略。所有新的连接在新策略上打开:

cowboy:set_env(my_http_listener, dispatch,
    cowboy_router:compile(Dispatch)).

注意到,我们在调用set_env更新路由之前先编译了路由:cowboy_router:compile(Dispatch)。

Erlang cowboy routing 路由的更多相关文章

  1. Erlang cowboy 处理简单的HTTP请求

    Erlang cowboy 处理简单的HTTP请求 原文出自: Handling plain HTTP requests 处理请求的最简单的方式是写一个简单的HTTP处理器.它的模型参照Erlang/ ...

  2. Erlang cowboy http request生命周期

    Erlang cowboy http request生命周期 翻译自: http://ninenines.eu/docs/en/cowboy/1.0/guide/http_req_life/ requ ...

  3. Erlang cowboy 入门参考

    Erlang cowboy 入门参考 cheungmine,2014-10-28 本文翻译自: http://ninenines.eu/docs/en/cowboy/HEAD/guide/gettin ...

  4. .NET/ASP.NET Routing路由(深入解析路由系统架构原理)

    阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4 ...

  5. .NET/ASP.NET Routing路由(深入解析路由系统架构原理)http://wangqingpei557.blog.51cto.com/1009349/1312422

    阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4 ...

  6. NET/ASP.NET Routing路由(深入解析路由系统架构原理)(转载)

    NET/ASP.NET Routing路由(深入解析路由系统架构原理) 阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模 ...

  7. Microsoft.AspNetCore.Routing路由

    Microsoft.AspNetCore.Routing路由 这篇随笔讲讲路由功能,主要内容在项目Microsoft.AspNetCore.Routing中,可以在GitHub上找到,Routing项 ...

  8. Erlang cowboy 处理不规范的client

    Erlang cowboy 处理不规范的client Cowboy 1.0 參考 本章: Dealing with broken clients 存在很多HTTP协议的实现版本号. 很多广泛使用的cl ...

  9. Routing路由

    Routing路由 新版Routing功能介绍 在ASP.NET 5和MVC6中,Routing功能被全部重写了,虽然用法有些类似,但和之前的Routing原理完全不太一样了,该Routing框架不仅 ...

随机推荐

  1. Afinal加载网络图片及下载文件使用方法

    Afinal快速开发框架使用起来非常方便,下面将讲解如何利用Afinal加载网络图片及下载文件: 先看效果图: 注意:使用Afinal前需添加Afinal的jar,可以在这里下载:http://dow ...

  2. SQL Server 索引维护(1)——如何获取索引使用情况

    前言: 在前面一文中,已经提到了三类常见的索引问题,那么问题来了,当系统出现这些问题时,该如何应对? 简单而言,需要分析现有系统的行为,然后针对性地对索引进行处理: 对于索引不足的情况:检查缺少索引的 ...

  3. JAVA面向对象-----抽象类注意细节

    抽象类可以没有抽象方法(java.awt.*的类就是这样子操作的). 抽象类可以继承普通类与抽象类. 抽象类不能直接使用类名创建实例,但是有构造方法,构造方法是让子类进行初始化. 抽象类一定有构造方法 ...

  4. java中的interface接口

    接口:java接口是一些方法表征的集合,但是却不会在接口里实现具体的方法. java接口的特点如下: 1.java接口不能被实例化 2.java接口中声明的成员自动被设置为public,所以不存在pr ...

  5. 1QPushButton的使用,QLineEdit的使用,设置组件位置,布局(QHBoxLayout,QGridLayout)

     1.新建一个空Qt项目 2 新建一个新的文件(右击项目à添加新文件) 3 配置pro文件属性 SOURCES += \ main.cpp QT += widgets gui 4 编写main.c ...

  6. 03_dbcp数据源依赖jar包,DBCP中API介绍,不同过dbcp方式使用dbcp数据库连接池,通过配置文件使用dbcp数据库连接池

     DBCP数据源 使用DBCP数据源,需要导入两个jar包 Commons-dbcp.jar:连接池的实现 Common-pool.jar:连接池实现的依赖库. 导入mysql的jar包. DBC ...

  7. 自定义控件辅助神器ViewDragHelper

    ViewDragHelper作为官方推出的手势滑动辅助工具,极大的简化了我们对手势滑动的处理逻辑,v4包中的SlidingPaneLayout和DrawerLayout内部都有ViewDragHelp ...

  8. OpenMP并行化实例----Mandelbrot集合并行化计算

    在理想情况下,编译器使用自动并行化能够管理一切事务,使用OpenMP指令的一个优点是将并行性和算法分离,阅读代码时候无需考虑并行化是如何实现的.当然for循环是可以并行化处理的天然材料,满足一些约束的 ...

  9. iOS开发之三:常用控件--UILabel的使用

    UILabel 一般用来显示文本内容. 常用的属性如下: @property(nonatomic,copy) NSString *text; // 文本的内容,默认为 nil @property(no ...

  10. 【Unity Shaders】Transparency —— 使用渲染队列进行深度排序

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...