您的位置:首頁 > 軟件教程 > 教程 > SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

來源:好特整理 | 時間:2024-08-13 09:57:12 | 閱讀:151 |  標(biāo)簽: a T Pi API Ri S in 開發(fā)   | 分享到:

接口服務(wù)主要由兩部分組成,即參數(shù)(輸入)部分,響應(yīng)(輸出)部分。其中在SpringBoot中主要是Controller層作為API的開發(fā)處,其實在架構(gòu)層面來講,Controller本身是一個最高的應(yīng)用層,它的職責(zé)是調(diào)用、組裝下層的interface服務(wù)數(shù)據(jù),核心是組裝和調(diào)用,不應(yīng)該摻雜其他相關(guān)的邏輯

寫在前面

博主最近在做一個數(shù)據(jù)服務(wù)的項目,而這個數(shù)據(jù)服務(wù)的核心就是對外暴露的API,值得高興的這是一個從0開始的項目,所以終于不用受制于“某些歷史”因素去續(xù)寫各種風(fēng)格的Controller,可以在項目伊始就以規(guī)范的技術(shù)和統(tǒng)一形式去搭建API。借此機會,梳理和匯總一下基于SpringBoot項目開發(fā)REST API的技術(shù)點和規(guī)范點。

接口服務(wù)主要由兩部分組成,即參數(shù)(輸入)部分,響應(yīng)(輸出)部分。其中在SpringBoot中主要是Controller層作為API的開發(fā)處,其實在架構(gòu)層面來講, Controller 本身是一個最高的應(yīng)用層,它的職責(zé)是調(diào)用、組裝下層的interface服務(wù)數(shù)據(jù),核心是組裝和調(diào)用,不應(yīng)該摻雜其他相關(guān)的邏輯。

但是往往很多項目里針對Controller部分的代碼都是十分混亂,有的 Controller 兼顧各種if else的參數(shù)校驗,有的甚至直接在Controller進(jìn)行業(yè)務(wù)代碼編寫;對于 Controller 的輸出,有的粗略的加個外包裝,有的甚至直接把service層的結(jié)構(gòu)直接丟出去;對于異常的處理也是各種各樣。

以上對于 Controller 相關(guān)的問題,這里統(tǒng)一用一系列 Controller 的封裝處理來提供優(yōu)化思路。優(yōu)雅且規(guī)范的開發(fā)REST API需要做以下幾步:

  • 接口版本控制
  • 參數(shù)校驗
  • 異常捕獲處理
  • 統(tǒng)一響應(yīng)封裝
  • 接口文檔的維護和更新

@RestController注解

直接來看@RestController源碼

@RestController注解等價于@Controller和@@ResponseBody,@ResponseBody注解的作用是告訴Spring MVC框架,該方法的返回值應(yīng)該直接寫入HTTP響應(yīng)體中,而不是返回一個視圖(View)。當(dāng)一個控制器方法被標(biāo)記為 @ResponseBody 時,Spring MVC會將方法的返回值序列化成JSON或XML等格式,然后發(fā)送給客戶端。更適用于REST API的構(gòu)建。

所以針對Controller接口的開發(fā), 直接使用@RestController為好。它會自動將Controller下的方法返回內(nèi)容轉(zhuǎn)為REST API的形式 。

例如:

接口版本管理

對于API來講,一般是對外服務(wù)的基礎(chǔ),不能隨意變更,但是隨著需求和業(yè)務(wù)不斷變化,接口和參數(shù)也會發(fā)生相應(yīng)的變化。此時盡可能保證“開閉原則”,以新增接口或增強接口功能來支撐,此時就需要對API的版本進(jìn)行維護,以版本號來確定同一接口的不同能力,一般版本都基于url來控制

例如:

進(jìn)行API版本控制主要分三步:

  • 定義版本號注解
  • 編寫版本號匹配邏輯處理器
  • 注冊處理器

定義版本號注解

該注解可直接使用在Controller類上

編寫版本號匹配邏輯處理器

首先定義一個條件匹配類,對應(yīng)解析Url中的version與ApiVersion注解

這里補充一下 RequestCondition 相關(guān)概念:

它是 Spring 框架中用于請求映射處理的一部分。在 Spring MVC 中, RequestCondition 接口允許開發(fā)者定義自定義的請求匹配邏輯,這可以基于請求的任何屬性,例如路徑、參數(shù)、HTTP 方法、頭部等。相關(guān)的應(yīng)用場景包括:

  1. 路徑匹配(Path Matching) :使用 PatternsRequestCondition 來定義請求的路徑模式,支持 Ant 風(fēng)格的路徑模式匹配,如 /api/* 可以匹配所有 /api 開頭的請求路徑 。

  2. 請求方法匹配(Request Method Matching) :通過 RequestMethodsRequestCondition 來限制請求的 HTTP 方法,例如只允許 GET 或 POST 請求 。

  3. 請求參數(shù)匹配(Request Params Matching) :使用 ParamsRequestCondition 來定義請求必須包含的參數(shù),例如某些接口可能需要特定的查詢參數(shù)才能訪問 。

  4. 請求頭匹配(Request Headers Matching) HeadersRequestCondition 允許定義請求頭的條件,例如某些接口可能需要特定的認(rèn)證頭部才能訪問 。

  5. 消費媒體類型匹配(Consumes Media Type Matching) ConsumesRequestCondition 用來定義控制器方法能夠處理的請求體媒體類型,通常用于 RESTful API 中,例如只處理 application/json 類型的請求體 。

  6. 產(chǎn)生媒體類型匹配(Produces Media Type Matching) ProducesRequestCondition 定義了控制器方法能夠返回的媒體類型,這通常與 Accept 請求頭結(jié)合使用以確定響應(yīng)的格式 。

  7. 自定義條件匹配 :開發(fā)者可以通過實現(xiàn) RequestCondition 接口來定義自己的匹配邏輯,例如根據(jù)請求中的版本號來路由到不同版本的 API,實現(xiàn) API 的版本控制 。

  8. 組合條件匹配(Composite Conditions Matching) :在某些情況下,可能需要根據(jù)多個條件來匹配請求, CompositeRequestCondition 可以將多個 RequestCondition 組合成一個條件來進(jìn)行匹配 。

  9. 請求映射的優(yōu)先級選擇(Priority Selection for Request Mapping) :當(dāng)存在多個匹配的處理器方法時, RequestCondition compareTo 方法用于確定哪個條件具有更高的優(yōu)先級,以選擇最合適的處理器方法 。

創(chuàng)建一個版本映射處理器,使用 ApiVersionCondition 作為自定義條件來處理請求映射。當(dāng) Spring MVC 處理請求時,它會使用這個自定義的映射處理器來確定哪個版本的 API 應(yīng)該處理請求。

注冊處理器

將上述的處理器注冊到SpringMvc的處理流程中

驗證:

針對test接口進(jìn)行不同版本的請求:

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

針對Account擴展版本調(diào)用上一版本接口

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

當(dāng)請求對應(yīng)的版本不存在接口時,會匹配之前版本的接口,即請求 /v2/account/extend 接口時,由于v2 控制器未實現(xiàn)該接口,所以自動匹配v1 版本中的接口。這就實現(xiàn)了 API版本繼承 。

參數(shù)校驗

@Validated注解

@Validated 是一個用于 Java 應(yīng)用程序中的注解,特別是在 Spring 框架中,以指示目標(biāo)對象或方法需要進(jìn)行驗證。這個注解通常與 JSR 303/JSR 380 規(guī)范的 Bean Validation API 結(jié)合使用,以確保數(shù)據(jù)的合法性和完整性。

@Validated注解的三種用法:

方法級別驗證 :當(dāng) @Validated 注解用在方法上時,它指示 Spring 在調(diào)用該方法之前執(zhí)行參數(shù)的驗證。如果參數(shù)不符合指定的驗證條件,將拋出 MethodArgumentNotValidException

類級別驗證 :將 @Validated 注解用在類上,表示該類的所有處理請求的方法都會進(jìn)行驗證。這可以減少在每個方法上重復(fù)注解的需要。

組合注解 :Spring 還提供了 @Valid 注解,它是 @Validated 的一個更簡單的形式,只觸發(fā)驗證并不指定特定的驗證組(Validation Groups)。 @Validated 允許你指定一個或多個驗證組,這在需要根據(jù)不同情況執(zhí)行不同驗證規(guī)則時非常有用。

使用注解進(jìn)行參數(shù)校驗

在REST API中進(jìn)行參數(shù)驗證一般使用方法級別驗證即可,即對參數(shù)Dto的類內(nèi)信息進(jìn)行驗證,例如一個分頁的查詢參數(shù)類:

在Controller中配合@Validated使用:

此時如果前端傳入?yún)?shù)不合法,例如pageNo為0又或者productType不存在,則會拋出 MethodArgumentNotValidException 的異常。稍后對于異常進(jìn)行處理即可完成參數(shù)的驗證。

這里的@Max 、 @Min @NotNull 注解屬于 Bean Validation API 的一部分,這是一個 JSR 303/JSR 380 規(guī)范,用于在 Java 應(yīng)用程序中提供聲明式驗證功能。這些注解用于約束字段值的范圍和非空性。類似的注解還有:

注解 作用

@NotNull

驗證注解的字段值不能為 null 。
@NotEmpty @NotNull 類似,但用于集合或字符串,驗證注解的字段值不能為 null ,且對于字符串,長度不能為 0。
@NotBlank 驗證注解的字段值不能為 null ,且不能是空白字符串(空白包括空格、制表符等)。
@Min(value) 驗證注解的字段值是否大于或等于指定的最小值。 value 參數(shù)接受一個整數(shù)。
@Max(value) 驗證注解的字段值是否小于或等于指定的最大值。 value 參數(shù)接受一個整數(shù)。
@Size(min, max) 驗證字符串或集合的大小在指定的最小值和最大值之間。
@Pattern(regex) 驗證字段值是否符合指定的正則表達(dá)式。

注:SpringBoot 2.3.1 版本默認(rèn)移除了校驗功能,如果想要開啟的話需要添加以上依賴

統(tǒng)一異常捕獲

@RestControllerAdvice注解

@RestControllerAdvice 是 @ResponseBody+@ControllerAdvice的集合注解,用于定義一個控制器級別的異常處理類。一般用來進(jìn)行全局異常處理,在 @RestControllerAdvice 類中處理異常后,可以直接返回一個對象,該對象會被轉(zhuǎn)換為 JSON 或 XML 響應(yīng)體,返回給客戶端。

使用@RestControllerAdvice注解處理參數(shù)異常

使用@Validated和 Bean Validation API 的注解進(jìn)行參數(shù)校驗后,當(dāng)出現(xiàn)不符合規(guī)定的參數(shù)會拋出 MethodArgumentNotValidException 異常 ,這里就可以使用@RestControllerAdvice注解來創(chuàng)建一個全局Controller異常攔截類,來統(tǒng)一處理各類異常

這里只以 MethodArgumentNotValidException 異常進(jìn)行攔截,在 @RestControllerAdvice類內(nèi)可以創(chuàng)建多個方法,通過@ExceptionHandler對不同的異常進(jìn)行定制化處理,這樣當(dāng)Controller內(nèi)發(fā)生異常,都可以在@RestControllerAdvice類內(nèi)進(jìn)行截獲、處理、返回給客戶端安全的信息。

統(tǒng)一響應(yīng)封裝

首先,進(jìn)行統(tǒng)一的響應(yīng)格式,這里需要封裝一個固定返回格式的結(jié)構(gòu)對象: ResponseData

統(tǒng)一狀態(tài)碼

其中對于相關(guān)的狀態(tài)碼最好進(jìn)行統(tǒng)一的封裝,便于以后的開發(fā),創(chuàng)建狀態(tài)枚舉:

統(tǒng)一返回結(jié)構(gòu)

將上述的 ResponseData 中狀態(tài)類相關(guān)替換為枚舉

這樣Controller的接口統(tǒng)一返回格式就是標(biāo)準(zhǔn)的結(jié)構(gòu)了。

統(tǒng)一封裝Controller響應(yīng)

有了統(tǒng)一響應(yīng)體的Controller在返回時可以這樣寫:

即便如此,團隊開發(fā)中可能還會出現(xiàn)換個人新寫Controller不知道有統(tǒng)一返回體這回事,為了更保險,可以通過AOP進(jìn)行統(tǒng)一對結(jié)果進(jìn)行封裝,不論Controller返回啥,到客戶端的數(shù)據(jù)都包含一個包裝體。

具體實現(xiàn)是使用 @RestControllerAdvice類 實現(xiàn) ResponseBodyAdvice 接口來完成。

我們以test接口為例,test接口原本返回的是String,而toint返回的是Integer

但是頁面返回是JSON字符串和返回體:

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

文檔:調(diào)試維護API利器—Swagger

接口開發(fā)完成,調(diào)試時,大多數(shù)都是使用Postman模擬請求調(diào)試或者直接用前端代碼調(diào)用調(diào)試,其實這兩種都比較麻煩,尤其面對復(fù)制參數(shù)時,Postman要逐個接口的錄入,十分費事,其實這里可以在SpringBoot中引入Swagger接口文檔組件,接口文檔和接口調(diào)試一并解決。

引入依賴

直接在maven中引入相關(guān)依賴:

標(biāo)準(zhǔn)的swagger3引入以上兩個依賴即可,相關(guān)版本可自行選擇

裝配配置類

下面進(jìn)行swagger的配置類和一些swagger相關(guān)頁面的配置

使用注解

Swagger相關(guān)注解明細(xì)

注解 使用位置 作用
@Api 作用在類上, Controller 表示對類的說明,通常用于描述 Controller 的作用和分類,如 @Api(tags = "用戶管理"),后續(xù)會在Swagger文檔中以 目錄形式 展示
@ApiOperation 作用在方法上,一般為 Controller中具體方法 描述 API 接口的具體操作和功能,例如 @ApiOperation(value = "獲取用戶列表", notes = "根據(jù)條件獲取用戶列表") ,在swagger文檔中以目錄內(nèi)容體現(xiàn)
@ApiModel 作用于類上,一般是 參數(shù)實體類 表示這是一個模型類,通常與 @ApiModelProperty 結(jié)合使用來描述模型屬性 。
@ApiModelProperty 用于模型類的屬性上, 參數(shù)類的成員變量 描述屬性的信息,如 @ApiModelProperty(value = "用戶名", required = true)
@ApiImplicitParams @ApiImplicitParam 用于方法上,一般為 Controller中具體方法 描述接口的隱含參數(shù),例如請求參數(shù)或請求頭信息
@ApiResponses @ApiResponse 用于方法上,一般為 Controller中具體方法 描述接口的響應(yīng)信息,可以指定不同的響應(yīng)狀態(tài)碼和對應(yīng)的描述信息 。
@ApiIgnore 用于類或方法上 表示忽略該類或方法,不將其顯示在Swagger文檔中。

@Api @ApiOperation 使用

@ApiMode @ApiModelProperty

@ApiImplicitParams @ApiImplicitParam

與ApiMode和ApiModeProperty功能一致,一般用于get請求中的參數(shù)描述

效果

使用swagger后,直接在頁面訪問 http://127.0.0.1:8080/XXX/doc.html即可訪問接口頁面

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

不要復(fù)雜的postman調(diào)用,本地調(diào)試可以直接使用調(diào)試功能

SpringBoot優(yōu)雅開發(fā)REST API最佳實踐

補充:完整的Controller類代碼模板

補充:完整的@RestControllerAdvice類代碼模板

關(guān)于參數(shù)驗證的異常處理和統(tǒng)一返回結(jié)構(gòu),可以使用一個類來完成,以下是完整模板:

小編推薦閱讀

好特網(wǎng)發(fā)布此文僅為傳遞信息,不代表好特網(wǎng)認(rèn)同期限觀點或證實其描述。

a 1.0
a 1.0
類型:休閑益智  運營狀態(tài):正式運營  語言:中文   

游戲攻略

游戲禮包

游戲視頻

游戲下載

游戲活動

《alittletotheleft》官網(wǎng)正版是一款備受歡迎的休閑益智整理游戲。玩家的任務(wù)是對日常生活中的各種雜亂物
RPG Ri序章 0.2.1
RPG Ri序章 0.2.1
類型:角色扮演  運營狀態(tài):正式運營  語言: 日文  

游戲攻略

游戲禮包

游戲視頻

游戲下載

游戲活動

《RPG_Ri序章》是GameMaker'Child-Dream'制作的一款幻想廢土風(fēng)RPG手游,完全免費的幻想廢土風(fēng)RPG登場!元

相關(guān)視頻攻略

更多

掃二維碼進(jìn)入好特網(wǎng)手機版本!

掃二維碼進(jìn)入好特網(wǎng)微信公眾號!

本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請發(fā)郵件[email protected]

湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2024 haote.com 好特網(wǎng)