Board logo

标题: RESTful Grails(1) [打印本页]

作者: look_w    时间: 2018-8-8 10:18     标题: RESTful Grails(1)

REST 简介当开发人员说要提供 RESTful Web 服务时,他们通常是指想要提供一个简单的、无争议的方法来从他们的应用程序中获取 XML。RESTful Web 服务通常提供一个可以响应 HTTP GET请求而返回 XML 的 URL(稍后我将给出 REST 的更正式的定义,它对这个定义进行了改良,虽然改动不大,但仍然很重要)。
Yahoo! 提供了大量的 RESTful Web 服务(参见 ),它们响应简单的 HTTP GET请求,而返回 POX。例如,在 Web 浏览器的位置字段键入 http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=YahooDemo&query=beatles。您将获得使用 XML 的 Web 搜索结果,它和在 Yahoo! 主页的搜索框里键入 beatles而获得的使用 HTML 的搜寻结果是一样的。
关于本系列Grails 是一种新型 Web 开发框架,它将常见的 Spring 和 Hibernate 等 Java™技术与当前流行的实践(比如约定优于配置)相结合。在加入脚本语言的灵活性和动态性的同时,用 Groovy 编写的 Grails 可以无缝地集成遗留的 Java 代码。学习完 Grails 之后,您将改变看待 Web 开发的方式。

如果假设 Yahoo! 支持 SOAP 接口的话(实际上并不支持),那么发出一个 SOAP 请求将会返回相同的数据,但对于开发人员来说,发出请求可能更费劲一些。在查询字符串里,请求方将需要呈交的不是简单的一组名称 / 值对,而是一份定义明确的、带有一个 SOAP 报头和正文部分的 XML 文档 —而且要用一个 HTTP POST而非 GET来提交请求。所有这些额外的工作完成后,响应会以一个正式 XML 文档的形式返回,它与请求一样,也有一个 SOAP 报头和正文部分,但要获得查询结果,需要去掉这些内容。Web 服务常常作为复杂 SOAP 的一种简单替代品而被采用。
有几种趋势可以表明 Web 服务的 RESTful 方法越来越普及了。Amazon.com 既提供了 RESTful 服务又提供了基于 SOAP 的服务。现实的使用模式表明十个用户中几乎有九个都偏爱 RESTful 接口。另外还有一个值得注意的情况,Google 于 2006 年 12 月正式宣布反对基于 SOAP 的 Web 服务。它的所有数据服务(归类为 Google Data API)都包含了一个更加具有 REST 风格的方法。
面向服务的 Web 服务如果把 REST 和 SOAP 之间的差异归结为 GET和 POST之间的优劣,那就很容易区分了。所使用的 HTTP 方法是很重要的,但重要的原因与您最初预想的不同。要充分了解 REST 和 SOAP 之间的差异,您需要先掌握这两个策略的更深层语义。SOAP 包含了一个 Web 服务的面向对象的方法 —其中包含的方法(或动词)是您与服务相交互的主要方式。REST 采取面向资源的方法,方法中的对象(或名词)是最重要的部分。   
在一个 SOA 中,一个服务调用看起来就像是一个远程过程调用(remote procedure call,RPC)。设想,如果您有一个带有 getForecast(String zipcode)方法的 Java Weather类的话,就可以轻易地将这个方法公开为一个 Web 服务了。实际上,Yahoo! 就有这样一个 Web 服务。在浏览器中输入 http://weather.yahooapis.com/forecastrss?p=94089,这样就会用你自己的 ZIP 代码来替代 p参数了。Yahoo! 服务还支持第二参数 —u—,该参数既接受华氏温度(Fahrenheit)符号 f,又接受摄氏温度(Celsius)符号 c。不难想象,在假想的类上重载方法签名就可以接受第二参数:getForecast("94089", "f")。
回过来再看一下我刚才做的 Yahoo! 搜索查询,同样,不难想象出,可以将它重写为一个方法调用。http://api.search.yahoo.com/WebSearchService  /V1/webSearch?appid=YahooDemo&query=beatles 轻松转换成了 WebSearchService.webSearch("YahooDemo", "beatles")。
所以如果 Yahoo! 调用实际上为 RPC 调用的话,那这跟我先前所称的 Yahoo! 服务是 RESTful 的岂不是互相矛盾的么?很不幸,就是矛盾的。但犯这种错误的不只我一个。Yahoo! 也称这些服务是 RESTful 的,但它也坦言:从最严格的意义上讲这些服务并不符合 RESTful 服务的定义。在 Yahoo! Web Services FAQ 中寻找 “什么是 REST ?”,答案是:“REST 代表 Representational State Transfer。大多数的 Yahoo! Web Services 都使用 ‘类 REST ’ 的 RPC 样式的操作,而非 HTTP GET或 POST……”
这个问题在 REST 社区内一直引发着争论。问题是没有准确的定义可以简单明了地描述这种 “较之 POST更偏好 HTTP GET的、较之 XML 请求更偏好简单的 URL 请求的、基于 RPC 的 Web 服务” 。有些人称之为 HTTP/POX 或者 REST/RPC 服务。其他人则对应 High REST Web 服务 —一种与 Fielding 的面向资源架构的定义更接近的服务 —而称之为 Low REST Web 服务。
我将类似 Yahoo! 的服务称为 GETful服务。这并不表示我看轻它 —正相反,我认为 Yahoo! 在整理不太正式的(low-ceremony)Web 服务的集合方面做的相当好。这个词恰到好处地概括出了 Yahoo! 的 RPC 样式的服务的益处 —通过发出一个简单的 HTTP GET请求来获得 XML 结果 —,而且没有滥用 Fielding 所作的原始定义。
面向资源的 Web 服务与 在 REST 社区存在着有关 POST和    PUT在插入新资源方面所起的作用的争议。在 HTTP 1.1 的原始的 RFC(Fielding 是主要作者)中对 PUT的定义称:如果不存在资源的话,服务器可以创建资源。而如果已经存在资源的话,那么 “……封装的实体必须被当作是对驻留在初始服务器上的实体修改后的版本”。因此如果不存在资源的话,PUT就等于 INSERT。如果存在资源的话,PUT就等于 UPDATE。 如果按如下的方式定义 POST的话,事情就复杂了:
“POST旨在用一个统一的方法来涵盖以下所有功能:
“注释现有资源” 似乎暗指 UPDATE,而 “将一则消息发布到告示板”、“扩展数据库” 似乎暗指 INSERT。
由于所有的浏览器在提交 HTML 表单数据时都不支持 PUT方法(它们只支持 GET和 POST),所以很难确定在哪种情况下使用哪种方法最为明智。
Atom 发布协议(Atom Publishing Protocol)是一个遵循 RESTful 原则的流行的聚合格式。Atom 的 RFC 作者试图给 POST与 PUT之间的争议做个了结:
“Atom Publishing Protocol 对如下的 Member Resource 使用 HTTP 方法:
在本文中,我将以 Atom 为指引,使用 POST来 INSERT,用 PUT来 UPDATE。但如果您在您的应用程序中反其道而行的话,那么也是可以的 —RESTful Web Services一书(参见 )支持使用 PUT来 INSERT。

那么要成为真正的面向资源的服务要满足哪些条件呢?可以这样归结:创建一个好的统一资源标识符(Uniform Resource Identifier,URI),并以标准化的方式来使用 HTTP 动词(GET、POST、PUT和 DELETE),而不是使用与自定义的方法调用相结合的动词(GET)。
再回到 Beatles 的查询上,要想更接近正式的 RESTful 接口,第一步就是要调试 URI。Beatles不是作为参数而被传入到 webSearch方法,而是成为了 URI 的中心资源。例如,关于 Beatles 的 Wikipedia 文章的 URI 为 http://en.wikipedia.org/wiki/Beatles
但是真正把 GETful 原理和 RESTful 原理区别开来的是用于返回资源表示的方法。Yahoo! RPC 接口定义了很多自定义方法(webSearch、albumSearch、newsSearch等等)。如果不读取文档的话,是无法得知方法调用的名称的。就 Yahoo! 而言,我可以跟随它的模式并猜出它有 songSearch、imageSearch和 videoSearch这几个方法调用,但却不敢保证一定是这样。同样,其他的 Web 站点可能使用不同的命名约定,如 findSong或者 songQuery。就 Grails 而言,像 aiport/list和 airport/show这样的自定义操作在整个应用程序内都是标准操作,但这些方法名称无法成为其他 Web 框架中的标准。
相反,RESTful 方法通常使用 HTTP GET来返回所涉及的资源表示。因此对于 Wikipedia 上的任何资源来说(http://en.wikipedia.org/wiki/Beatleshttp://en.wikipedia.org/wiki/United_Airlines 或者 http://en.wikipedia.org/wiki/Peanut_butter_and_jelly_sandwich),我都可以得知 GET是获取它的标准方式。
当处理一个资源的完整的 Create/Retrieve/Update/Delete(CRUD)生命周期时,标准化的方法调用的强大功能就变得更加显而易见了。RPC 接口不提供创建新资源的标准化方式。自定义的方法调用可以是 create、new、insert、add抑或是其他任何调用。在 RESTful 接口中,每向 URI 发送一个 POST请求就会插入一个新资源。PUT可以更新资源,而 DELETE可以删除资源(参见 侧边栏)。
现在您已经对 GETful 与 RESTful Web 服务之间的差异有了更充分的了解了,并已经准备好用 Grails 创建自己的服务了。这两种服务的例子您都将看得到,但我要从简单的 POX 例子开始说起。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0