推薦閱讀:
吊打所有敢于提問JVM問題的面試官,JVM調優實戰訓練營
SpringMVC、Dubbo 都支援 REST 服務,那當我們要開發一個 REST 服務接口時,該如何選擇? 本文将包括以下兩方面内容:
- REST服務的寫法
- REST服務的應用場景
1. REST服務的寫法
首先我們看下 SpringMVC 怎麼實作一個 REST 服務:
@[email protected]("/greetings")public class SpringRestController { @RequestMapping(method = RequestMethod.GET, value = "/{name}", produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity> greeting(@PathVariable String name) { String greeting = "Hello " + name; return new ResponseEntity<>(greeting, HttpStatus.OK); }}
使用過 SpringMVC 的同學都很熟悉這些注解吧,@RestController、@RequestMapping、@PathVariable。
在了解 Dubbo 是如何實作 REST 服務之前,先簡單聊下 Dubbo 中關于 REST 的那部分曆史。Dubbo 于 2011 年開源,而 2014 年 開始發展停滞。早些時候的 Dubbo 是不支援 REST 的,而如果要實作一個 REST 服務,也是有辦法的,可以結合 SpringMVC,在 Controller 中調 Dubbo 的服務。但是 REST 這麼火,想直接在 Dubbo 上支援 REST 怎麼辦?2014年,當當 Fork 了一個 Dubbo 版本開始維護,命名為 DubboX,并增加了 REST 風格的遠端調用。後來随着 Dubbo 和 DubboX 的合并,Dubbo 将 DubboX 中對 REST 的支援合并了進來。
聊完這段架構史,下面我們來一起看 Dubbo 是如何實作 REST 服務的:
@Path("/greetings")public class DubboService { @GET @Path("/{name}") @Produces(MediaType.TEXT_PLAIN) public Response greeting(@PathParam("name") String name) { String greeting = "Hello " + name; return Response.ok(greeting).build(); }}
從中可以看出 Dubbo 使用的注解不同于 SpringMVC,@Path、@GET和@PathParam。這套注解是 JAX-RS 規範所定義的。關于 JAX-RS,這是标準的 Java REST API,具體的開源實作有 Oracle 的 Jersey、RedHat 的 RestEasy、Apache 的 CXF 和 Wink 以及 Restlet 等等。而 Dubbo 則是使用了 RestEasy 來支援 REST 服務。
既然 Java REST 都已經有了 JAX-RS 标準了,為啥 SpringMVC 不使用這套标準?我猜想主要原因應該是 SpringMVC 本身已有一套自己的注解了,如 @RequestMapping在沒有 REST 之前就在使用了,是以在支援 REST 時,仍考慮使用原有的注解風格。
2. REST服務的應用場景
第 1 節已對 SpringMVC、Dubbo 寫法的不同之處進行了介紹。那如何根據應用場景進行選擇。我們首先看下 Dubbo 的一些 REST 應用場景:
- 企業内部的異構系統之間的(跨語言)調用。Dubbo 的系統做服務提供端,其他語言的系統(也包括某些不基于 Dubbo 的 Java 系統)做服務消費端,兩者通過HTTP和文本消息進行通信。即使相比 Thrift、ProtoBuf 等二進制跨語言調用方案,REST也有自己獨特的優勢。
- 對外 Open API(開放平台)的開發。既可以用 Dubbo 來開發專門的 Open API 應用,也可以将原内部使用的 Dubbo Service 直接“透明”釋出為對外的Open REST API。
- 簡化手機(平闆)APP 或者 PC 桌面用戶端開發。類似于第 2 點,既可以用Dubbo 來開發專門針對無線或者桌面的伺服器端,也可以将原内部使用的Dubbo Service 直接”透明“的暴露給手機APP或桌面程式。
- 簡化浏覽器 AJAX 應用的開發。類似于第 2 點,既可以用 Dubbo 來開發專門的 AJAX 伺服器端,也可以将原内部使用的 Dubbo Service 直接”透明“的暴露給浏覽器中 JavaScript。當然,很多 AJAX 應用更适合與 Web 架構協同工作,是以直接通路 Dubbo Service 在很多 Web 項目中未必是一種非常優雅的架構。
- 為企業内部的 Dubbo系統之間提供一種基于文本的、易讀的遠端調用方式 ,即服務提供端和消費端都是基于 Dubbo 的系統。
- 一定程度簡化 Dubbo 系統對其它異構系統的調用。可以用類似 Dubbo 的簡便方式“透明”的調用非 Dubbo 系統提供的 REST 服務(不管服務提供端是在企業内部還是外部)。就是第 1 點的更新版。
其中的 1、2、3 點被認為是 Dubbo 的 REST 服務最有價值的三種應用場景,提供 REST 服務來提供給非 Dubbo 的(異構)消費端。
而 SpringMVC 則更适合于面向 Web 應用的 REST 服務,如第 3 點中的 AJAX 調用。這也正符合 MVC 的概念,REST 服務為 View 層的一種實作。
使用 JAX-RS 的 Dubbo 則更适合純粹的服務化應用,将 Service 這類 Bean 釋出成 REST 服務。
筆者認為如果是一個面向 Web 的單體應用,那應該使用 SpringMVC,完全不用考慮 Dubbo。而如果是一個微服務應用,使用了 Dubbo 作為 RPC 架構,而這時候又需要面向 Web,那應該直接使用 Dubbo 将服務以 REST 方式進行釋出,沒必要為了 REST 再引入 SpringMVC ,過于複雜,而且實作的效果都是一樣的。
作者:草捏子
連結:https://juejin.im/post/5e70c0ccf265da575477aefc