Spring Boot 2.x基礎教程:Swagger接口分類與各元素排序問題詳解

2021-02-19 程序猿DD

點擊藍色「程序猿DD」關注我

回復「資源」獲取獨家整理的學習資料!

作者 | 翟永超

來源 | didispace.com/spring-boot-learning-21-2-4/

之前通過Spring Boot 2.x基礎教程:使用Swagger2構建強大的API文檔一文,我們學習了如何使用Swagger為Spring Boot項目自動生成API文檔,有不少用戶留言問了關於文檔內容的組織以及排序問題。所以,就特別開一篇詳細說說Swagger中文檔內容如何來組織以及其中各個元素如何控制前後順序的具體配置方法。

接口的分組

我們在Spring Boot中定義各個接口是以Controller作為第一級維度來進行組織的,Controller與具體接口之間的關係是一對多的關係。我們可以將同屬一個模塊的接口定義在一個Controller裡。默認情況下,Swagger是以Controller為單位,對接口進行分組管理的。這個分組的元素在Swagger中稱為Tag,但是這裡的Tag與接口的關係並不是一對多的,它支持更豐富的多對多關係。

默認分組

首先,我們通過一個簡單的例子,來看一下默認情況,Swagger是如何根據Controller來組織Tag與接口關係的。定義兩個Controller,分別負責教師管理與學生管理接口,比如下面這樣:

@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {

@GetMapping("/xxx")
public String xxx() {
return "xxx";
}

}

@RestController
@RequestMapping(value = "/student")
static class StudentController {

@ApiOperation("獲取學生清單")
@GetMapping("/list")
public String bbb() {
return "bbb";
}

@ApiOperation("獲取教某個學生的老師清單")
@GetMapping("/his-teachers")
public String ccc() {
return "ccc";
}

@ApiOperation("創建一個學生")
@PostMapping("/aaa")
public String aaa() {
return "aaa";
}

}

啟動應用之後,我們可以看到Swagger中這兩個Controller是這樣組織的:

圖中標出了Swagger默認生成的Tag與Spring Boot中Controller展示的內容與位置。

自定義默認分組的名稱

接著,我們可以再試一下,通過@Api註解來自定義Tag,比如這樣:

@Api(tags = "教師管理")
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {



}

@Api(tags = "學生管理")
@RestController
@RequestMapping(value = "/student")
static class StudentController {



}

再次啟動應用之後,我們就看到了如下的分組內容,代碼中@Api定義的tags內容替代了默認產生的teacher-controller和student-controller。

合併Controller分組

到這裡,我們還都只是使用了Tag與Controller一一對應的情況,Swagger中還支持更靈活的分組!從@Api註解的屬性中,相信聰明的讀者一定已經發現tags屬性其實是個數組類型:

我們可以通過定義同名的Tag來匯總Controller中的接口,比如我們可以定義一個Tag為「教學管理」,讓這個分組同時包含教師管理和學生管理的所有接口,可以這樣來實現:

@Api(tags = {"教師管理", "教學管理"})
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {



}

@Api(tags = {"學生管理", "教學管理"})
@RestController
@RequestMapping(value = "/student")
static class StudentController {



}

最終效果如下:

更細粒度的接口分組

通過@Api可以實現將Controller中的接口合併到一個Tag中,但是如果我們希望精確到某個接口的合併呢?比如這樣的需求:「教學管理」包含「教師管理」中所有接口以及「學生管理」管理中的「獲取學生清單」接口(不是全部接口)。

那麼上面的實現方式就無法滿足了。這時候發,我們可以通過使用@ApiOperation註解中的tags屬性做更細粒度的接口分類定義,比如上面的需求就可以這樣子寫:

@Api(tags = {"教師管理","教學管理"})
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {

@ApiOperation(value = "xxx")
@GetMapping("/xxx")
public String xxx() {
return "xxx";
}

}

@Api(tags = {"學生管理"})
@RestController
@RequestMapping(value = "/student")
static class StudentController {

@ApiOperation(value = "獲取學生清單", tags = "教學管理")
@GetMapping("/list")
public String bbb() {
return "bbb";
}

@ApiOperation("獲取教某個學生的老師清單")
@GetMapping("/his-teachers")
public String ccc() {
return "ccc";
}

@ApiOperation("創建一個學生")
@PostMapping("/aaa")
public String aaa() {
return "aaa";
}

}

效果如下圖所示:

內容的順序

在完成了接口分組之後,對於接口內容的展現順序又是眾多用戶特別關注的點,其中主要涉及三個方面:分組的排序、接口的排序以及參數的排序,下面我們就來逐個說說如何配置與使用。

分組的排序

關於分組排序,也就是Tag的排序。目前版本的Swagger支持並不太好,通過文檔我們可以找到關於Tag排序的配置方法。

第一種:原生Swagger用戶,可以通過如下方式:

第二種:Swagger Starter用戶,可以通過修改配置的方式:

swagger.ui-config.tags-sorter=alpha

似乎找到了希望,但是其實這塊並沒有什麼可選項,一看源碼便知:

public enum TagsSorter {
ALPHA("alpha");

private final String value;

TagsSorter(String value) {
this.value = value;
}

@JsonValue
public String getValue() {
return value;
}

public static TagsSorter of(String name) {
for (TagsSorter tagsSorter : TagsSorter.values()) {
if (tagsSorter.value.equals(name)) {
return tagsSorter;
}
}
return null;
}
}

是的,Swagger只提供了一個選項,就是按字母順序排列。那麼我們要如何實現排序呢?這裡筆者給一個不需要擴展源碼,僅依靠使用方式的定義來實現排序的建議:為Tag的命名做編號。比如:

@Api(tags = {"1-教師管理","3-教學管理"})
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {



}

@Api(tags = {"2-學生管理"})
@RestController
@RequestMapping(value = "/student")
static class StudentController {

@ApiOperation(value = "獲取學生清單", tags = "3-教學管理")
@GetMapping("/list")
public String bbb() {
return "bbb";
}



}

由於原本存在按字母排序的機制在,通過命名中增加數字來幫助排序,可以簡單而粗暴的解決分組問題,最後效果如下:

接口的排序

在完成了分組排序問題(雖然不太優雅...)之後,在來看看同一分組內各個接口該如何實現排序。同樣的,凡事先查文檔,可以看到Swagger也提供了相應的配置,下面也分兩種配置方式介紹:

第一種:原生Swagger用戶,可以通過如下方式:

第二種:Swagger Starter用戶,可以通過修改配置的方式:

swagger.ui-config.operations-sorter=alpha

很慶幸,這個配置不像Tag的排序配置沒有可選項。它提供了兩個配置項:alpha和method,分別代表了按字母表排序以及按方法定義順序排序。當我們不配置的時候,改配置默認為alpha。兩種配置的效果對比如下圖所示:

參數的排序

完成了接口的排序之後,更細粒度的就是請求參數的排序了。默認情況下,Swagger對Model參數內容的展現也是按字母順序排列的。所以之前教程中的User對象在文章中展現如下:

如果我們希望可以按照Model中定義的成員變量順序來展現,那麼需要我們通過@ApiModelProperty註解的position參數來實現位置的設置,比如:

@Data
@ApiModel(description = "用戶實體")
public class User {

@ApiModelProperty(value = "用戶編號", position = 1)
private Long id;

@NotNull
@Size(min = 2, max = 5)
@ApiModelProperty(value = "用戶姓名", position = 2)
private String name;

@NotNull
@Max(100)
@Min(10)
@ApiModelProperty(value = "用戶年齡", position = 3)
private Integer age;

@NotNull
@Email
@ApiModelProperty(value = "用戶郵箱", position = 4)
private String email;

}

最終效果如下:

小結

本文詳細的介紹了Swagger中對接口內容的組織控制。有些問題並沒有通過配置來解決,也可能是對文檔或源碼內容的了解不夠深入。如果讀者有更好的實現方案,歡迎提出與交流。

代碼示例

本文的完整工程可以查看下面倉庫中的chapter2-4目錄:

如果您覺得本文不錯,歡迎Star支持,您的關注是我堅持的動力!

相關資料

本文通過OpenWrite的免費Markdown轉換工具發布

-END-

留言交流不過癮

關注我,回復「加群」加入各種主題討論群

朕已閱 

相關焦點

  • Spring Boot 2.x基礎教程:使用Swagger2構建強大的API文檔
    為了減少與其他團隊平時開發期間的頻繁溝通成本,傳統做法就是創建一份RESTful API文檔來記錄所有接口細節,然而這樣的做法有以下幾個問題:為了解決上面這樣的問題,本文將介紹RESTful API的重磅好夥伴Swagger2,它可以輕鬆的整合到Spring Boot中,並與Spring MVC程序配合組織出強大RESTful API文檔。
  • Spring Boot 2.x基礎教程:快速入門
    Spring Boot:選用的Spring Boot版本;這裡將使用當前最新的 2.1.3版本。Project Metadata:項目的元數據;其實就是Maven項目的基本元素,點開More options可以看到更多設置,根據自己組織的情況輸入相關數據,比如:
  • 芋道 Spring Boot API 接口文檔 Swagger 入門
    問題二,接口不規範。 當團隊裡沒有同意明確的接口規範時,又或者代碼 Review 做的不是很好的情況下,千奇百怪、各式各樣的 API 接口可能就產生了。前端在對接這樣的 API 接口,苦不堪言,在一口 mmp 一嘴 fuck xxx 之中,調完接口。問題三,接口文檔更新不及時,或者遺忘更新。
  • Spring Boot 禁用 Swagger 的三種方式
    配置,避免暴露接口的這種危險行為。;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;
  • Spring Boot 使用 Swagger3 生成 API 接口文檔
    回憶一下,我們集成 Swagger2 時,引入的依賴如下:<dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger2</artifactId>    &
  • webflux 與swagger2.x
    由於為人比較懶,所以不想單獨去寫開發文檔,所以webflux與swagger2.x就成了我該篇主題!注意事項:如果是一個負責人的分享者,他的代碼一定會儘可能的通熟易懂,如果你跑不起來項目,首先是自己環境搭建好了麼?然後在懷疑作者的上傳是不是又點兒問題?
  • Spring Boot 集成 Swagger-Bootstrap-UI,頁面更清爽!
    後來覺得它不太好用,在瀏覽技術網站的時候,偶然發現swagger-bootstrap-ui,於是便重構了,把swagger-bootstrap-ui整合進來,後來發現不僅僅對我們後端有幫助,主要方便我們將接口進行歸類,同樣對安卓小夥伴也有幫助,他們可以看這個接口文檔進行聯調。
  • Spring Boot 集成 Swagger-Bootstrap-UI,非常棒的解決方案
    當初我使用swagger-boostrap-ui的時候,那個時候還是1.x版本,如今swagger-bootsrap-ui到2.x,同時也更改名字knife4j,適用場景從過去的單體到微服務。也算是見證咱們國人自己的開源項目從小到大。PS:如果需要 Swagger 相關的教程,可以關注公眾號「Java後端」獲取推送。
  • Spring Boot 2.x基礎教程:使用MongoDB
    既然稱為NoSQL資料庫,Mongo的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支持對數據建立索引。但是,MongoDB也不是萬能的,同MySQL等關係型資料庫相比,它們在針對不同的數據類型和事務要求上都存在自己獨特的優勢。
  • 技術分享 | Spring Boot 集成 Swagger
    ;聯調方便,如果出問題,直接測試接口,實時檢查參數和返回值,就可以快速定位問題。-- swagger --><dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version></dependency>&
  • 芋道 Spring Boot Elasticsearch 入門
    spring-boot-starter-data-jest :3.2.5.RELEASE本小節,我們會使用 spring-boot-starter-data-jest 自動化配置 Spring Data Jest 主要配置。同時,編寫相應的 Elasticsearch 的 CRUD 操作。
  • 嘗鮮剛發布的 SpringFox 3.0.0,以前造的輪子可以不用了...
    <dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger2</artifactId>    <version>3.0.0</version
  • Spring Boot 2.x 實戰--SQL資料庫(Spring Data JPA)
    大數據小先博客主頁:https://me.csdn.net/u010974701原始碼倉庫:https://github.com/zhshuixian/learn-spring-boot-2上一小節主要介紹了 Spring Boot  2.x 實戰--整合 Log4j2 與 Slf4j 實現日誌列印和輸出到文件。
  • 終於放棄了單調的swagger-ui了,選擇了這款神器...
    個性化配置項,支持接口地址、接口description屬性、UI增強等個性化配置功能...接口排序、Swagger資源保護、導出Markdown、參數緩存眾多強大功能...# 功能預覽knife4j-extensionchrome瀏覽器的增強swagger接口文檔ui,快速渲染swagger資源knife4j-service為swagger服務的一系列接口服務程序knife4j-frontknife4j-spring-ui的純前端靜態版本,用於集成非Java語言使用swagger-bootstrap-uiknife4j的前身,最後發布版本是1.9.6
  • 比Swagger功能更強大的竟然是它!
    更名後主要專注的方面2.項目模塊目前主要的模塊包括:增強接口排序、Swagger資源保護、導出Markdown、參數緩存眾多強大功能…4.業務場景不使用增強功能,純粹換一個swagger的前端皮膚不使用增強功能,純粹換一個swagger的前端皮膚。
  • 終於放棄了單調的swagger-ui了,選擇了這款神器—knife4j
    個性化配置項,支持接口地址、接口description屬性、UI增強等個性化配置功能...接口排序、Swagger資源保護、導出Markdown、參數緩存眾多強大功能...網關對任意微服務文檔進行組合集成knife4j-extensionchrome瀏覽器的增強swagger接口文檔ui,快速渲染swagger資源knife4j-service為swagger服務的一系列接口服務程序knife4j-frontknife4j-spring-ui的純前端靜態版本,用於集成非Java語言使用swagger-bootstrap-uiknife4j的前身,最後發布版本是1.9.6
  • Swagger 3.0 官方 starter 誕生,野生的可以扔了!
    相關資料springfox 官網:springfox[2]springfox Github 倉庫:springfox / springfox[3]springfox-demos Github 倉庫:springfox / springfox-demos[4]springfox Maven 倉庫:Home » io.springfox[5]swagger介紹
  • Spring Boot 2.x基礎教程:實現文件上傳
    第二步:在pom.xml中引入模版引擎依賴:<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-thymeleaf</artifactId
  • SpringBoot 實戰 | 集成 Swagger2 構建強大的 RESTful API 文檔
    微信公眾號:一個優秀的廢人如有問題或建議,請後臺留言,我會盡力解決你的問題。前言快過年了,不知道你們啥時候放年假,忙不忙。反正我是挺閒的,所以有時間寫 blog。今天給你們帶來 SpringBoot 集成 Swagger2 的教程。
  • 架構實戰篇(六):Spring Boot RestTemplate的使用
    </artifactId>    <version>1.0-SNAPSHOT</version>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent<