我们经常说的REST Service其实全称应该为RESTful Web Service,即REST Service 的实质还是Web Service,当这种Web Service符合REST的风格,就称这个Web Service为RESTful Web Service即REST Service。
什么是Web Service[1]?
Web Service 技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。
Web Service 常用的技术有XML, HTML, HTTP, WSDL, SOAP, MQ等。
另外IBM的WebSphere的软件平台,也全部提供了对Web Service技术的支持,正所以有对这些开放标准的全面支持,WebSphere软件在企业平台上能得到灵活的扩展和便捷的维护,这正是这种软件能被业界广泛采用的原因。这个不同于微软的不开放源代码的风格。
什么是REST[2]风格?
根据之前的一篇研究REST Service的文章,REST风格的Web Service必须遵循以下四个基本设计原则:
- 显式地使用HTTP标准方法(GET, POST, PUT, DELETE)。
- 无状态。
- 公开目录结构式的URI。
- 传输XML或JSON,或同时传输这两者。
这四个基本原则里面,有必要对第一点做一个详细的说明。
根据HTTP1.1规范,HTTP协议定义了很多标准方法,其中最重要的是GET和POST方法,因为GET和POST方法能满足客户端和服务器端交互的全部需求。
不论是GET还是POST方法,都是给服务器端发送Request,只是他们遵循的原理不一样。在一定程度上看,这两种方法最终结果都是一样的,过程确有所不同。
- GET方法: 指客户端向服务器端发送获取数据的Request
这种方法由于将参数放在URL里面传输,比较方便,进而被大量采用。但是GET方法并非安全的方法,并且由于是放在URL里面而非request body里面传输,所以提交的数据量有限制,但POST方法理论上是没有限制的。
- POST方法: 指客户端向服务器端发送修改数据的Requst
如提交form和上传文件,数据被包含在request body里面。
综上所述,使用REST风格的web service是回归了HTTP的标准方法,从而降低了开发的复杂度。另外无状态的数据设计原则则将服务器端大量的有状态的操作转移到了客户端,这样有助于分布式系统的架构,特别是目前互联网高并发,高负载的设计开发显得尤其重要。
如何使用?
在Cloud Marketplace项目中有CategoryViewHandler.findTopCategories() 这个REST Service,我们借这个例子来分析前台页面是如何调用REST Service的。
REST Service: CategoryViewHandler.findTopCategories()
作用: 获取所有顶级的类目及其子类目。
URL Response:
{ "catalogGroupView": [ { "childCatalogGroupID": [ "12501_10852", "12501_11351", "12501_10853", "12501_11352" ], "identifier": "IBM Software", "name": "IBM Software", "parentCatalogGroupID": "-1", "resourceId": "http:\/\/localhost\/search\/resources\/store\/18251\/categoryview\/byId\/10851", "shortDescription": "IBM Software products", "storeID": "18151", "uniqueID": "10851" }, { "childCatalogGroupID": "12501_12352", "identifier": "ibm_marketplace", "name": "Ibm_marketplace", "parentCatalogGroupID": "-1", "resourceId": "http:\/\/localhost\/search\/resources\/store\/18251\/categoryview\/byId\/12351", "storeID": "18151", "thumbnail": "\/wcsstore\/SCWExtendedSitesCatalogAssetStore\/\/images\/blank.png", "uniqueID": "12351" } ], "recordSetComplete": "true", "recordSetCount": 2, "recordSetStartNumber": 0, "recordSetTotal": 2, "resourceId": "http:\/\/localhost\/search\/resources\/store\/18251\/categoryview\/@top?catalogId=12501&depthAndLimit=&responseFormat=json&responseFormat=json&langId=-1", "resourceName": "categoryview" }
(URL从表象看,是符合REST设计风格的,并且reponse是JSON,也是符合REST设计原理的)
使用方法: 在JSP页面中,使用wcf:rest标签直接发送rest call,并且将response存储在var代表的变量中,如下面的代码片段:
<wcf:rest var="newcatalog" url="${searchHostNamePath}${searchContextPath}/store/${WCParam.storeId}/categoryview/@top" > <c:if test="${!empty WCParam.langId}"> <wcf:param name="langId" value="${WCParam.langId}"/> </c:if> <c:if test="${empty WCParam.langId}"> <wcf:param name="langId" value="${langId}"/> </c:if> <wcf:param name="responseFormat" value="json"/> <wcf:param name="catalogId" value="${WCParam.catalogId}"/> </wcf:rest>
然后可以使用jstl或者直接写${newcatalog}的方式调用REST Service response,如下:
<h2>${newcatalog}</h2>
返回结果如下:
{"recordSetTotal":2,"resourceName":"categoryview","resourceId":"http:\/\/localhost\/search\/resources\/store\/18251\/categoryview\/@top?catalogId=12501&responseFormat=json&responseFormat=json&langId=-1","recordSetStartNumber":0,"recordSetComplete":"true","catalogGroupView":[{"shortDescription":"IBM Software products","resourceId":"http:\/\/localhost\/search\/resources\/store\/18251\/categoryview\/byId\/10851","identifier":"IBM Software","parentCatalogGroupID":"-1","name":"IBM Software","uniqueID":"10851","storeID":"18151","childCatalogGroupID":["12501_10852","12501_11351","12501_10853","12501_11352"]},{"resourceId":"http:\/\/localhost\/search\/resources\/store\/18251\/categoryview\/byId\/12351","identifier":"ibm_marketplace","parentCatalogGroupID":"-1","name":"Ibm_marketplace","uniqueID":"12351","thumbnail":"\/wcsstore\/SCWExtendedSitesCatalogAssetStore\/\/images\/blank.png","storeID":"18151","childCatalogGroupID":"12501_12352"}],"recordSetCount":2}
这个返回结果跟上面直接用HTTP request的方式返回的Response一致。
总结
在某种意义上,通过强调URI和HTTP等早期Internet标准,REST是对大型应用程序服务器时代之前的Web方式的回归。
RESTful Web Service对专有中间件(例如某个应用程序服务器)的依赖比传统的Web Service更少,因此减少了开发复杂度,提升了系统的可伸缩性,它作为一种设计Web服务的方法变得越来越流行。
参考资料:
[1].http://baike.baidu.com/view/67105.htm
[2].http://blog.csdn.net/alli0968/article/details/42121567