精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

到底什么樣的REST才是最佳REST?

OSC開源社區 ? 來源:OSC開源社區 ? 2023-01-17 10:14 ? 次閱讀

說起 REST API,小伙伴們多多少少都有聽說過,但是如果讓你詳細介紹一下什么是 REST,估計會有很多人講不出來,或者只講出來其中一部分。

今天松哥就來和大家一起來聊一聊到底什么是 REST,順便再來看下 Spring HATEOAS 的用法。

1. REST 成熟模型

首先關于 REST,有一個大佬 Leonard Richardson 為 REST 定義了一個成熟度模型,他一共定義了四個不同的層次,分別如下:

Level0:Web 服務單純的使用 HTTP 作為數據傳輸方式,本質上就是遠程方法調用,常見的 SOAP 和 RPC 基本上都屬于這一類。

Level1:在這一級別上,引入了資源的概念,服務端的每一個資源,都有一個對應的操作地址。

Level2:在這一級別上,我們引入了不同的 HTTP 請求方法來描述不同的操作,例如 GET 表示查詢、POST 表示插入、PUT 表示更新、DELETE 表示刪除,并且使用 HTTP 的狀態碼來表示不同的響應結果。一般來說,大家在日常的接口開發中,基本上都能做到這一層級。但是這還不是最佳結果。

Level3:按照 Leonard Richardson 的意思,這一層級的 REST 基于 HATEOAS(Hypertext As The Engine Of Application State),在這一級別上,除了返回資源的 JSON 之外,還會額外返回一組 Link,這組 Link 描述了對于該資源可以做哪些操作,以及具體的該怎么做。

在日常的開發中,我們一般都是只實現到 Level2 這一層級,真正做到 Level3 的估計很少,不過雖然在工作中一般不會做到 Level3 這一層級,但是,我相信很多小伙伴應該是見過 Level3 層級的 REST 是啥樣子的,特別是看過 vhr 視頻的小伙伴,松哥在其中講過,通過 Spring Data Jpa+Spring Rest Repositories 實現的 CURD 接口,其實就是一個達到了 Level3 層級的 REST。

2. Spring HATEOAS

那么接下來我先用 Spring HATEOAS 寫一個簡單的 REST,然后結合這個案例來和小伙伴們聊一聊到底 Spring HATEOAS 有何不一樣的地方。

首先我們創建一個 Spring Boot 工程,引入 Web 和 Spring HATEOAS 依賴,如下:

99163e5a-95bf-11ed-bfe3-dac502259ad0.png

創建好之后,我們首先創建一個 User 實體類:

publicclassUserextendsRepresentationModel{
privateIntegerid;
privateStringusername;
privateStringaddress;
//省略getter/setter
}

注意這個 User 實體類需要繼承自 RepresentationModel,以方便后續添加不同的 Link(以前舊的版本需要繼承自 ResourceSupport)。

接下來寫一個簡單的測試接口。

查詢所有用戶:

@RestController
@RequestMapping("/users")
publicclassUserController{

@GetMapping
publicCollectionModellist(){
Listlist=newArrayList<>();
Useru1=newUser();
u1.setId(1);
u1.setUsername("javaboy");
u1.setAddress("www.javaboy.org");
u1.add(WebMvcLinkBuilder.linkTo(UserController.class).slash(u1.getId()).withSelfRel());
list.add(u1);
Useru2=newUser();
u2.setId(2);
u2.setUsername("itboy");
u2.setAddress("www.itboyhub.com");
u2.add(WebMvcLinkBuilder.linkTo(UserController.class).slash(u2.getId()).withSelfRel());
list.add(u2);
CollectionModelusers=CollectionModel.of(list);
users.add(WebMvcLinkBuilder.linkTo(UserController.class).withRel("users"));
returnusers;
}
}

關于這個接口,我來說幾點:

首先,對于這種返回一個集合或者數組的情況,返回的類型都是 CollectionModel。

把集合弄好之后(正常應該去數據庫中查詢,我這里省事直接創建了),通過 CollectionModel.of(list) 方法去獲取一個 CollectionModel 對象。

對于每一個 user 對象,我都添加了一個 Link 對象,WebMvcLinkBuilder.linkTo(UserController.class).slash(u1.getId()).withSelfRel() 表示生成當前對象的訪問鏈接。

WebMvcLinkBuilder.linkTo(UserController.class).withRel("users") 表示訪問所有數據的鏈接。

好了,這個接口寫完之后,我們訪問看下:

993a43ea-95bf-11ed-bfe3-dac502259ad0.png

可以看到,返回的每一個 user 對象中,都有一個鏈接表示如何單獨訪問這個對象。最下面還有一個訪問所有對象的鏈接。

對于上面這個案例,可能有小伙伴會質疑,難道我們從數據庫中查詢出來的 List 集合都要遍歷一遍,然后給每一個 User 添加一個 Link 嗎?其實不必,添加 Link 這個事可以直接在 User 類中完成,如下:

publicclassUserextendsRepresentationModel{
privateIntegerid;
privateStringusername;
privateStringaddress;

publicUser(Integerid){
super(WebMvcLinkBuilder.linkTo(UserController.class).slash(id).withSelfRel());
this.id=id;
}
//省略getter/setter
}

可以看到,直接在構造方法中完成即可。此時接口里就不用那么復雜了,如下:

@GetMapping
publicCollectionModellist(){
Listlist=newArrayList<>();
Useru1=newUser(1);
u1.setUsername("javaboy");
u1.setAddress("www.javaboy.org");
list.add(u1);
Useru2=newUser(2);
u2.setUsername("itboy");
u2.setAddress("www.itboyhub.com");
list.add(u2);
CollectionModelusers=CollectionModel.of(list);
users.add(WebMvcLinkBuilder.linkTo(UserController.class).withRel("users"));
returnusers;
}

那么對于根據 ID 來查詢用戶的需求,我們也應該給一個接口如下:

@RestController
@RequestMapping("/users")
publicclassUserController{

@GetMapping("/{id}")
publicEntityModelgetOne(@PathVariableIntegerid)throwsNoSuchMethodException{
Useru=newUser(id);
u.setUsername("javaboy");
u.setAddress("深圳");
u.add(Link.of("http://localhost:8080/users/"+id,"getOne"));
Linkusers=WebMvcLinkBuilder.linkTo(UserController.class).withRel("users");
u.add(users);
Linklink=WebMvcLinkBuilder.linkTo(UserController.class).slash(u.getId()).withSelfRel();
u.add(link);
Methodmethod=UserController.class.getMethod("getOne",Integer.class);
Linklink2=WebMvcLinkBuilder.linkTo(method,id).withSelfRel();
u.add(link2);
returnEntityModel.of(u);
}
}

關于這個接口,我說如下幾點:

如果返回類型是一個對象的話,需要使用 EntityModel 類型。

搞好返回的對象之后,通過 EntityModel.of(u) 方法可以獲取到目標數據類型。

這個地方,為了給小伙伴們演示不同的 Link 添加方式,我寫了好多個(單純為了演示不同的 Link 添加方式):

Link.of("http://localhost:8080/users/"+id, "getOne") 這種是自己純手工去生成當前對象的訪問鏈接,很明顯這不是一個很好的方案。當前對象的訪問鏈接建議使用上文中提到的方式。

WebMvcLinkBuilder.linkTo(UserController.class).withRel("users") 這個是生成當前這個 Controller 的訪問鏈接,一般就是訪問所有用戶對象的鏈接。

WebMvcLinkBuilder.linkTo(UserController.class).slash(u.getId()).withSelfRel() 前文已經用過了,不多說了,實際應用中建議使用這種。

也可以根據某一個方法自動生成,像這樣 WebMvcLinkBuilder.linkTo(method, id).withSelfRel(),這個是生成某一個具體方法的訪問鏈接。

好了,現在我們來看下這個接口生成的 JSON,如下:

994bfaae-95bf-11ed-bfe3-dac502259ad0.png

生成的這段 JSON 我將之標記為了三部分:

第一部分,self,就是自身的訪問鏈接,這三個鏈接分別是 User 的構造方法,以及前面提到的 3.3 和 3.4 的方法生成的。

第二部分,getOne 這個,是前面 3.1 中提到的方法生成的。

第三部分,users 這個,是前面提到的 3.2 方法生成的。

當然,其實這塊還有很多其他的生成鏈接的玩法,但是我就不一一介紹了,小伙伴們可以參考官方文檔:

https://docs.spring.io/spring-hateoas/docs/current/reference/html

從上面 Spring HATEOAS 中返回的 JSON 我們大致上可以看到它的特點:

當我們使用了 Spring HATEOAS,此時,客戶端就會通過服務端返回的 Link Rel 來獲取請求的 URI(如果沒有使用 Spring HATEOAS,則客戶端訪問的 URI 都是提前在客戶端硬編碼的),現在我們就可以做到服務端在不破壞客戶端實現的情況下動態的完成 URI 的修改,從而進一步解耦客戶端和服務端。

簡而言之,現在客戶端能干什么事情,在服務端返回的 JSON 中都會告訴客戶端,客戶端從服務端返回的 JSON 中獲取到請求的 URL,然后直接執行即可。如果這個請求地址發生變化的話,客戶端也會及時拿到最新的地址。

可能上面的例子小伙伴們感受還不是很明顯,我再給大家看一段 JSON:

{
"tracking_id":"666",
"status":"WAIT_PAYMENT",
"items":[
{
"name":"book",
"quantity":1
}
],
"_Links":{
"self":{
"href":"http://localhost:8080/orders/666"
},
"cancel":{
"href":"http://localhost:8080/orders/666"
},
"payment":{
"href":"http://localhost:8080/orders/666/payments"
}
}
}

這是電商系統下單之后等待支付的過程中返回的 JSON,這里的 links 給出了三個:

self:訪問這個鏈接可以查看當前訂單信息(GET 請求)。

cancel:訪問這個鏈接可以取消當前訂單(DELETE 請求)。

payment:訪問這個鏈接可以支付當前訂單(POST 請求)。

這個例子就很直白了,就是在返回的 JSON 中,直接告訴你接下來能做哪些操作,對應的 URL 分別是什么,前端拿到之后直接操作,如果這些操作路徑發生了變化,前端也會立馬拿到最新的路徑。

這就是 Spring HATEOAS 的好處??傊痪湓挘琒pring HATEOAS 提倡在響應返回的 Link 中給出對該資源接下來操作的 URL。這種方式解耦了服務端 URI,也可以讓客戶端開發者更容易地探索 API。

3. REST 的優缺點

雖然我們現在都鼓勵設計 REST 風格的 API,然而 REST 也不全是優點,事物總是具有兩面性,REST 的優缺點分別如下。

3.1 優點

首先,REST 足夠簡單,有一定 Web 開發經驗的小伙伴都可以快速上手 REST。

REST 風格的接口測試起來也非常方便,利用瀏覽器自帶的一些 REST 插件或者是 POSTMAN 之類的工具,就可以非常方便的實現 REST 接口的測試。

不需要中間代理,簡化了系統的結構。

HTTP 對防火墻比較友好。

3.2 缺點

REST 只支持請求-響應通信方法,不支持服務端推送消息到客戶端。

給請求取一個合適的名字比較困難,特別是有多個相類似的接口時,例如有多個添加接口、多個更新接口等。

由于沒有中間代理,所以請求/響應的時候,服務端和客戶端都必須在線。

好啦,跟小伙伴們聊了 REST 和 Spring HATEOAS,感興趣的小伙伴可以去試試哦~

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8496

    瀏覽量

    150834
  • API
    API
    +關注

    關注

    2

    文章

    1484

    瀏覽量

    61811
  • 模型
    +關注

    關注

    1

    文章

    3171

    瀏覽量

    48711
  • spring
    +關注

    關注

    0

    文章

    338

    瀏覽量

    14308
  • REST
    +關注

    關注

    0

    文章

    32

    瀏覽量

    9398

原文標題:到底什么樣的REST才是最佳REST?

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    War3Rest.exe下載

    War3Rest.exe
    發表于 10-04 07:46 ?0次下載
    War3<b class='flag-5'>Rest</b>.exe下載

    REST學習

    學習REST必備
    發表于 07-05 15:22 ?15次下載

    REST、gRPC、GraphQL及WebHook的對比和選型

    首先REST--Resource Representational State Transfer, 中文直譯就是資源在網絡中以某種表現形式進行狀態轉移。
    發表于 06-13 10:34 ?2453次閱讀

    REST端口支持構建動態REST請求來使用RESTful API網絡

    REST端口支持構建動態REST請求來使用RESTful API網絡服務。 概覽 REST端口暴露了一個簡單的接口來為REST請求構建頭、授權、主體和HTTP方法。請求體可以在端口配置
    的頭像 發表于 01-17 09:11 ?4793次閱讀

    REST API是什么,如何使用REST端口

    API是Application Programming Interface(應用程序接口)的縮寫,它是拿來描述一個類庫的特征或是如何去運用它。按照目前比較主流的分法,可以分為REST API和非
    的頭像 發表于 02-17 18:00 ?9183次閱讀
    <b class='flag-5'>REST</b> API是什么,如何使用<b class='flag-5'>REST</b>端口

    yii2-rest-rbac Yii2權限管理RBAC rest接口

    ./oschina_soft/gitee-yii2-rest-rbac.zip
    發表于 06-30 09:35 ?0次下載
    yii2-<b class='flag-5'>rest</b>-rbac Yii2權限管理RBAC <b class='flag-5'>rest</b>接口

    如何使用Spring構建REST服務(一)

    關于 REST 如何適應微服務世界還有一個更大的討論,但是——對于本教程——讓我們看看構建 RESTful 服務。
    的頭像 發表于 07-28 15:59 ?888次閱讀

    使用vRealize Automation REST API置備虛擬機以進行軟件開發

      本文面向希望使用 vRealize Automation REST API 以編程方式配置和管理 vRealize Automation 的軟件工程師和應用程序開發人員。本文還提供了用于置備藍圖
    的頭像 發表于 12-02 11:34 ?726次閱讀

    使用REST框架控制您的MKR1000

    電子發燒友網站提供《使用REST框架控制您的MKR1000.zip》資料免費下載
    發表于 12-12 11:21 ?0次下載
    使用<b class='flag-5'>REST</b>框架控制您的MKR1000

    使用REST使用Meadow和MAUI遠程控制伺服

    電子發燒友網站提供《使用REST使用Meadow和MAUI遠程控制伺服.zip》資料免費下載
    發表于 01-31 09:26 ?0次下載
    使用<b class='flag-5'>REST</b>使用Meadow和MAUI遠程控制伺服

    具有HTTP Rest通信的機器人(Pytobot)

    電子發燒友網站提供《具有HTTP Rest通信的機器人(Pytobot).zip》資料免費下載
    發表于 06-14 11:11 ?0次下載
    具有HTTP <b class='flag-5'>Rest</b>通信的機器人(Pytobot)

    SANnav管理門戶 REST API參考手冊

    電子發燒友網站提供《SANnav管理門戶 REST API參考手冊.pdf》資料免費下載
    發表于 09-01 15:02 ?0次下載
    SANnav管理門戶 <b class='flag-5'>REST</b> API參考手冊

    IDEA REST Client使用教程

    REST真香之前,postman(chrome的一款插件)確實是一個非常不錯的選擇,具有完備的REST Client功能和請求歷史記錄功能。但是當使用了IDEA REST之后,postman就可以丟了,因為
    的頭像 發表于 09-24 14:56 ?1005次閱讀
    IDEA <b class='flag-5'>REST</b> Client使用教程

    REST的6大指導原則

    1. 前言 REST 全稱為 :Resource Representational State Transfer. 是一種分布式超媒體系統( distributed hypermedia
    的頭像 發表于 10-09 14:27 ?1491次閱讀

    使用 Splashtop REST API 簡化遠程管理

    Splashtop 的 REST API 可無縫提高生產力和簡化集成,使用戶能夠自動執行任務、定制工作流程,輕松與現有系統集成。
    的頭像 發表于 06-25 17:28 ?254次閱讀
    使用 Splashtop <b class='flag-5'>REST</b> API 簡化遠程管理