热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[翻译][erlang]cowboy路由模块使用

Cowboy是基于Erlang实现的一个轻量级、快速、模块化的httpweb服务器。本文官方原文:http:ninenines.eudocsencowboy1.0guiderouti

Cowboy是基于Erlang实现的一个轻量级、快速、模块化的http web服务器。

本文官方原文:http://ninenines.eu/docs/en/cowboy/1.0/guide/routing/

默认情况下,Cowboy不会做什么事情。
为了使Cowboy可用,需要映射URL和处理请求的Erlang模型(Module),这个过程,我们称之为路由(routing)。
当Cowboy接收到一个请求,通过路由,Cowboy就会尝试去匹配到相应请求的主机和资源路径。如果匹配成功,那么相关的Erlang代码就会被执行。
每个主机会给出相应的路由规则。Cowboy首先会匹配主机,然后尝试寻找匹配的路径。
在使用Cowboy之前需要先编译路由。

1. Structure(结构)

路由一般定义成以下结构

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

每个主机包含匹配规则(HostMatch)、限制规则(非必须)(Constraints)和一个由路径组成的路由列表(PathsList)。

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

由路径组成的路由列表与主机列表类似。

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

而路径(path)包含匹配路径规则、限制规则(非必须)、处理逻辑的module和会被初始化的选项参数。

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

下面内容为匹配语法和限制选项。

2. Match syntax(匹配语法)

匹配语法用来关联主机名字和相应的handler路径。
主机的匹配语法和路径的匹配语法类似,只有轻微的区别。譬如,他们分隔符是不一样的。而且主机是从最后开始匹配的,而路径是不是。
(其实说了老半天,这不就是一个普通的URL嘛。URL的前半部分为主机IP或域名,这里称之为HOST,即主机。而后半部分为路径)
除了特殊情况,最简单的匹配就是只有主机或者只有路径的匹配。他的值可以为string() 或binary() 类型。

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

HostMatch1 = "cowboy.example.org".

正如你所见,所有的路径都是由斜杠开始的。注意,下面两条路径对于路由而言是一样的。

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

而对于主机名,最后有点和没有点对于路由来说也是一样的。同样,在前面多一个点和少一个点也是一样的。

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

因此能够提取主机和路径的数据段并且存储在Req 对象供后面使用。我们称之为值绑定。
绑定语法非常简单。由冒号字符(:)开头,一直到数据段的结尾的这个数据段是我们的绑定名称,会被保存。

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

如果这两个最终匹配,那么就会有两个绑定定义,分布是:subdomain 和:name ,每个包含被定义的数据段。例如,这个URL地址 http://test.example.org/hats/wild_cowboy_legendary/prices 会将 test绑定到subdomain ,并将wild_cowboy_legendary 绑定到 name 。他们通过cowboy_req:binding/{2,3} 函数检索出来的。绑定名字必须是原子(atom)类型。

还有一种特殊的绑定名字,它模仿erlang的下划线变量。任意内容都能与下划线(_)相匹配,但是数据会被丢弃。最有用的场景就是去匹配多个域名。

HostMatch = "ninenines.:_".

类似地,也可以添加可选内容。中括号内的内容都是可选的。

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

并且可选内容可以内嵌

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

还可以使用[...] 来获取主机名或路径剩余的部分。匹配主机的时候,需要放在最前面;匹配路径的时候是放在最后面。分别使用cowboy_req:host_info/1 和 cowboy_req:path_info/1 函数可以找到他们。

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

如果一个绑定变量出现了两次,那么只有这两个位置的值相同的时候才会匹配成功。

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

在可选变量里面也是一样的,在下面这个例子中,如果可选变量有值,必须两个绑定变量的值都一样才可匹配到。

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

如果一个绑定变量出现在主机名和路径当中,他们需要是相同的才能匹配。

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

当然也有两种特殊情况,第一种使用下划线变量(_)可以匹配任意的主机名和路径。

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

第二种,使用通配符星号(*)来匹配。

HostMatch = "*".

3. Constraints(约束)

关于这段没看懂,下面是英文原文:

After the matching has completed, the resulting bindings can be tested against a set of constraints. Constraints are only tested when the binding is defined. They run in the order you defined them. The match will succeed only if they all succeed.

They are always given as a two or three elements tuple, where the first element is the name of the binding, the second element is the constraint's name, and the optional third element is the constraint's arguments.

The following constraints are currently defined:

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

The int constraint will check if the binding is a binary string representing an integer, and if it is, will convert the value to integer.

The function constraint will pass the binding value to a user specified function that receives the binary value as its only argument and must return whether it fulfills the constraint, optionally modifying the value. The value thus returned can be of any type.

Note that constraint functions SHOULD be pure and MUST NOT crash.

4. Compilation(编译/收集)

在传递给Cowboy之前,定义的结构首先要先编译。才能是Cowboy有效查找到正确的handler,并执行,而不必重复地解析路由。
编译通过调用cow_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}。

5. Live update(热更新)

使用cowboy:set_env/3 函数可以更新当前的路由列表。这会应用到所有的监听器中。

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

注意,设置之前还是需要编译的哦。


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • position属性absolute与relative的区别和用法详解
    本文详细解读了CSS中的position属性absolute和relative的区别和用法。通过解释绝对定位和相对定位的含义,以及配合TOP、RIGHT、BOTTOM、LEFT进行定位的方式,说明了它们的特性和能够实现的效果。同时指出了在网页居中时使用Absolute可能会出错的原因,即以浏览器左上角为原始点进行定位,不会随着分辨率的变化而变化位置。最后总结了一些使用这两个属性的技巧。 ... [详细]
author-avatar
shangce
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有