面向服务的 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 所作的原始定义。