使用Erlang和Yaws开发REST式的服务

看过那张很出名的“Apache vs. Yaws”图么?是不是在考虑你也应该使用Yaws了?这些图给人的第一印象是,Yaws在可伸缩性上具有难以置信的巨大优势,它可以扩展到80000个并行的连接,而 Apache只接入4000个连接后就无法继续支撑了。人们对这些图的反应存在着明显的分化,一种声音说“这些图不太可能是准确的”或者“他们一定没有正确地配置Apache”;另一种声音则完全相反,“Wow,我要尝试一下Yaws!”

\

无论你是否相信上面的Yaws对比图,Yaws的确是一个可靠的Web Server,可以处理动态内容。Claes Wikström使用Erlang开发了Yaws,“另一个Web Server(Yet Another Web Server)”。Erlang是一种编程语言,特别用于支持长时间运行的、并发的、高可靠的分布式系统。(要学习更多关于Erlang的知识,可以去看那本很精彩的“Programming Erlang”,它的作者是Erlang语言的创建者——Joe Armstrong。)Yaws的灵活性和Erlang的多种独一无二的特性相结合,使得它们成为了一个不可忽视的REST式的Web服务平台。如果你处理的是静态页面,去试试lighttpd或者nginx吧,但是如果你在写动态的、REST式的Web服务,那么Yaws是绝对值得尝试的。在这篇文章中,我将讲述我在使用Yaws和Erlang开发Web服务中的一些经验。

\

Yaws基础

\

Yaws提供了若干种处理动态Web内容以及支持REST式的Web服务的方法:

\
  • \

    在静态页面中嵌入Erlang代码。通过这种方法,你可以将...标签内的out/1函数直接嵌入到静态页面中。该函数包含了Erlang代码。这样的文件要以.yaws 为扩展名,从而通知Yaws处理它,并将...标签替换为执行out/1函数的结果,这正是页面应该包含的。在Erlang的术语中,out/1是元数(arity)1的函数,例如,某个带有一个参数的函数。这个参数应该是一个Yaws arg记录(record),这是一种特殊的数据结构,Yaws使用它将接收到的请求的细节传递给处理它们的代码。例如,一个arg记录可以提供请求URI、请求头、POST 数据等信息。

    \ \
  • \

    应用程序模块(appmod)。由于Yaws的appmod,应用程序代码可以控制URI。在前面描述的方法中,Erlang代码被嵌入到静态文件中了,而这些文件的URI是由它们的路径相对于Web Server的文档根决定的。然而,有了appmod后,应用程序就会控制URI的含义,这些URI通常不会与任何文件系统上的工件有联系。Appmod 基本上都是一个导出out/1函数的Erlang模块。这些模块要在Yaws配置文件中进行配置,来关联一个URI路径元素。如果一个请求中包含了某个已注册的appmod所关联的路径元素,Yaws会调用这个模块的out/1 arg记录。模块的out/1函数可以继续解释URI剩下的部分,以此来解释请求和响应目标的具体资源是什么。

    \ \
  • \

    Yaws应用程序(yapp)。appmods通常仅仅是单一的Erlang模块,Yaws yapp与此不同,它是全功能的应用程序。每个yapp都有它自己的文档根,都有它自己的appmod集。说得明确些,yapp就是Erlang/OTP 应用程序。OTP表示“Open Telecom Platform(开发电信平台)”,它是一系列历经考验的库和框架,它们为Erlang程序带来了强大的能力。OTP封装了很多构建分布式、事件驱动、高可用性系统的模式和方法。Erlang/OTP已经在现实世界中获得了证明,它们可以被用在不同的电信系统中,例如,某些系统宣称它们的宕机时间每年不过几毫秒而已。

    \ \

上述这三种方法(它们的细节可以在Yaws站点上找到)都可以有效地应用在REST式的Web Service中。具体情况就要依赖于Service本身的特征了。但是根据我的经验,yapp和appmod是最好用的,因为它们提供了对Web应用程序的最大控制。

\

REST式的设计

\

既然我们打算要开发REST式的Web服务,那么首先了解一下REST的相关细节。REST的全称是“表象化状态转变(Representational State Transfer)”。Roy T. Fielding博士在他的论文中首次提出了“REST”这个术语,用它来描述一个适用于高可扩展性分布式系统(比如Web)的架构风格。HTTP本质上就是REST的一个实现。术语“表象化状态转换”是指REST式的系统通过在请求和响应之间交换资源状态的表象,来完成各种操作。例如,对于一个典型的从HTTP GET获得的Web页面来说,它就是Web资源的一个HTML表象,通过URI来标识,并由GET来触发。

\

开发REST式的Web服务需要注意下面几点:

\
  • \

    资源与资源标识符

    \ \
  • \

    每种资源支持的方法

    \ \
  • \

    数据在客户端与服务端之间交换所使用的格式

    \ \
  • \

    状态码

    \ \
  • \

    每个请求和响应的HTTP头

    \ \

让我们把目光集中在Yaws和Erlang中,逐一地看看上面列出的几个问题。

\

资源标识符

\

设计REST式的Web服务时,需要你考虑组成服务的资源,比如如何最佳地标识它们、其中一个如何与另一个相关联。REST式的资源由URI来标识。通常,资源都拥有一个与它们自身相关的URI,同时共享一个公共的路径元素。例如,在一个基于Web的Bug追踪系统中,所有 “Phoenix”项目(一个虚构的项目)中的bug都可以在http://www.example.com/projects/Phoenix/bugs/下找到,只要指明一个bug号就可以了,比如bug 12345的URI可能就是http://www.example.com/projects/Phoenix/bugs/12345/。REST式的资源还能够提供自身状态表象内部的其他资源的URI。对于一个获得特定资源状态的用户,可以使用这个返回的URI(包含在状态表象中)来导航到整个Web应用中的其他部分上。

\

在Yaws中,arg记录指定了请求的URI,使用yaws_api模块提供的request_url方法可以很容易地获得它:

\
out(Arg) -\u0026gt;
Uri = yaws_api:request_url(Arg),
Path = string:tokens(Uri#url.path, \"/\"),
\

一旦你得到了请求URI,那么可以像上面那样很方便地对请求路径切词,这要按照“/”进行分割就可以了。切词后可以得到路径元素的列表,它的起点是appmod的根节点。例如,假设我们将一个appmod绑定到“projects”路径元素上,完整的URI是http://www.example.com/projects/。如果一个请求URI的前缀是前面的URI,那么appmod的out/1函数从中获取一个分离的路径元素列表,代表了请求的目标资源。例如,一个URI为 http://www.example.com/projects/Phoenix/bugs/的请求,在执行过上面的一段代码后,Path 变量将保存下面的路径元素的列表:

\
[\"projects\
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值