1.2 解读REST服务
RESTful对应的中文是REST式的,RESTful
Web Service的准确翻译应该是REST式的Web服务,我们通常简称为REST服务。RESTful的应用或者Web服务是最常见的两种REST式的项目部署、存在的方式。本节将介绍REST服务并对比其与传统Web Services的不同。
1.2.1 REST式的Web服务
RESTful Web Service是一种遵守REST式风格的Web服务。REST服务是一种ROA(Resource-Oriented
Architecture,面向资源的架构)应用。其主要特点是方法信息存在于HTTP协议的方法中(比如GET、PUT),作用域存在于URI中。例如,在一个获取设备资源列表的GET请求中,方法信息是GET,作用域信息是URI中包含的对设备资源的过滤、分页和排序等条件。
1.2.2 对比RPC风格
相比Web服务领域广为流行的RPC(Remote Procedure Call Protocol,远程过程调用协议)风格,REST风格更轻量和快速。从方法信息角度看,REST采用标准的HTTP方法,而RPC请求都是HTTP协议的POST方法,其方法信息包含于SOAP协议包或HTTP协议包中,方法名称不具有通用性。从作用域角度看,REST采用URI显式定义作用域,而RPC的这一信息同样包含于协议包中,不能直观呈现。
RPC风格的开发关注于服务器–客户端之间的方法调用,而不关注基于哪个网络层的哪种协议。也就是说,RPC是面向方法调用过程的,相比而言,REST是面向资源状态的。RPC风格的两个代表是XML-RPC和大Web服务。
1. XML-RPC
XML-RPC是一种使用XML格式封装方法调用,并使用HTTP协议作为传送机制的RPC风格的实现。XML-RPC的请求方法都是HTTP协议的POST方法,请求和响应的数据格式均为XML。
XML-RPC的数据格式和使用XML作为资源的表述的REST外观上很相似,但数据的内容则大相径庭。REST式的XML信息的主体是对一个资源状态的表述,无须包含方法信息,因为其请求的HTTP方法就已经决定了这一点。XML-RPC的请求数据结构额外包含方法调用信息和参数信息。
对于响应信息的内容两者也截然不同,REST式通常会包含响应实体信息,以及HTTP状态码和可选的异常信息,而XML-RPC的返回信息仅仅是对方法调用的响应信息。
XML-RPC是一种遗留技术,已经被SOAP取代。在Java领域,JAX-RPC标准已经并入JAX-WS2标准。XML-RPC的应用依然存在,著名的测试用例管理系统TestLink的对外接口就是使用PHP开发的XML-RPC。
2. 大Web服务
大Web服务(Big Web Service)是Leonard Richardson和Sam Ruby在其所著的《RESTful Web Services》一书中,对基于SOAP+ WSDL+UDDI+WS-标准栈等技术实现RPC风格的大型Web服务的统称。事实上,“大Web服务”这一说法也被Java EE 7的布道者们在多次演讲中使用。在Java领域,对应的标准主要是JAX-WS 2.0/2.1/2.2(JSR 224)。相较REST式的Web服务,大Web服务功能更强大,设计更复杂。大Web服务同样是跨平台、跨语言的,对复杂的数据类型的支持也非常好。大Web服务是基于RPC风格的重量设计,因此方法和作用域无法通过直观断定,需要定义在消息中,而且方法名不是统一和通用的。同时,大Web服务走HTTP协议时,请求都是基于POST方法的。
对比RPC风格的Web服务,REST式的Web服务形式更简单、设计更轻量、实现更快捷。REST无须引入SOAP消息传输层,无须注册服务,也没有客户端stub的概念等。但是,REST式的Web服务并没有像大Web服务那样提供诸如安全策略等全面的标准规范。
大Web服务和REST式的Web服务各有优势,并不是一种替换关系。在实际开发中,两者共存于一个项目中也是一种解决方案。
1.2.3 对比MVC风格
MVC风格的出现将模型、视图、控制解耦,其亮点是从前到后的一致性,其结构整洁、逻辑清晰,易于扩展和增强。MVC在Java领域的普遍实现方式是在Web前端使用标签库来对应服务端的模型类实例和控制类实例,标签库和服务端依赖库可以是松散的耦合,比如Spring生态系统,也可以是全栈式的统一体系,比如JSF体系。但无论如何实现,在Web前端的开发过程中,必须时刻考虑页面标签和服务端的映射关系,包括模型类的匹配和转换、数据结构、控制类的输入和输出的参数类型和数量等。
因此,MVC风格偏重于解决服务器端的逻辑分层问题,以及客户端是逻辑分层的延伸问题。MVC的标签库虽然其形态已经和HTML页面融合,但本质上还是Java编写的装饰模式的类实例,对应的是服务器端使用Java编写的模型类或者控制器类,因此MVC很难实现跨语言解耦。而REST风格偏重于统一接口,因此具体实现就可以跨平台和跨语言。REST推动了Web开发的新时代,使用平庸的纯HTML作为客户端,没有服务器端和客户端的耦合。显而易见,使用纯HTML开发的REST客户端和使用Java开发的REST服务器端并不存在语言上的耦合。
MVC和REST式并不是互斥的,如Spring的MVC模块已经开始支持REST式的开发。Jersey作为JAX-RS标准的实现,也实现了MVC的功能,请参考相关模块:jersey-mvc、jersey-mvc-freemarker和jersey-mvc-jsp。需要说明的是,本书致力于讲述JAX-RS,对于Jersey实现中的JAX-RS之外的功能,只做必要的讲述。由于MVC和REST之间有更多的并行存在性,本书余文没有将MVC放入讲述之列。