今天,我們來(lái)講講Swagger中文檔內(nèi)容如何來(lái)組織以及其中各個(gè)元素如何控制前后順序的具體配置方法。
接口的分組
我們?cè)赟pring Boot中定義各個(gè)接口是以Controller
作為第一級(jí)維度來(lái)進(jìn)行組織的,Controller
與具體接口之間的關(guān)系是一對(duì)多的關(guān)系。我們可以將同屬一個(gè)模塊的接口定義在一個(gè)Controller
里。默認(rèn)情況下,Swagger是以Controller
為單位,對(duì)接口進(jìn)行分組管理的。這個(gè)分組的元素在Swagger中稱(chēng)為Tag
,但是這里的Tag
與接口的關(guān)系并不是一對(duì)多的,它支持更豐富的多對(duì)多關(guān)系。
一、默認(rèn)分組
首先,我們通過(guò)一個(gè)簡(jiǎn)單的例子,來(lái)看一下默認(rèn)情況,Swagger是如何根據(jù)Controller來(lái)組織Tag與接口關(guān)系的。定義兩個(gè)Controller
,分別負(fù)責(zé)教師管理與學(xué)生管理接口,比如下面這樣:
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {
@GetMapping("/xxx")
public String xxx() {
return "xxx";
}
}
@RestController
@RequestMapping(value = "/student")
static class StudentController {
@ApiOperation("獲取學(xué)生清單")
@GetMapping("/list")
public String bbb() {
return "bbb";
}
@ApiOperation("獲取教某個(gè)學(xué)生的老師清單")
@GetMapping("/his-teachers")
public String ccc() {
return "ccc";
}
@ApiOperation("創(chuàng)建一個(gè)學(xué)生")
@PostMapping("/aaa")
public String aaa() {
return "aaa";
}
}
啟動(dòng)應(yīng)用之后,我們可以看到Swagger中這兩個(gè)Controller是這樣組織的:
圖中標(biāo)出了Swagger默認(rèn)生成的Tag
與Spring Boot中Controller
展示的內(nèi)容與位置。
二、自定義默認(rèn)分組的名稱(chēng)
接著,我們可以再試一下,通過(guò)@Api
注解來(lái)自定義Tag
,比如這樣:
@Api(tags = "教師管理")
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {
// ...
}
@Api(tags = "學(xué)生管理")
@RestController
@RequestMapping(value = "/student")
static class StudentController {
// ...
}
再次啟動(dòng)應(yīng)用之后,我們就看到了如下的分組內(nèi)容,代碼中@Api定義的tags內(nèi)容替代了默認(rèn)產(chǎn)生的teacher-controller和student-controller。
三、合并Controller分組
到這里,我們還都只是使用了Tag
與Controller
一一對(duì)應(yīng)的情況,Swagger中還支持更靈活的分組!從@Api
注解的屬性中,相信聰明的讀者一定已經(jīng)發(fā)現(xiàn)tags
屬性其實(shí)是個(gè)數(shù)組類(lèi)型:
我們可以通過(guò)定義同名的Tag來(lái)匯總Controller中的接口,比如我們可以定義一個(gè)Tag為“教學(xué)管理”,讓這個(gè)分組同時(shí)包含教師管理和學(xué)生管理的所有接口,可以這樣來(lái)實(shí)現(xiàn):
@Api(tags = {"教師管理", "教學(xué)管理"})
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {
// ...
}
@Api(tags = {"學(xué)生管理", "教學(xué)管理"})
@RestController
@RequestMapping(value = "/student")
static class StudentController {
// ...
}
最終效果如下:
四、更細(xì)粒度的接口分組
通過(guò)@Api
可以實(shí)現(xiàn)將Controller
中的接口合并到一個(gè)Tag
中,但是如果我們希望精確到某個(gè)接口的合并呢?比如這樣的需求:“教學(xué)管理”包含“教師管理”中所有接口以及“學(xué)生管理”管理中的“獲取學(xué)生清單”接口(不是全部接口)。
那么上面的實(shí)現(xiàn)方式就無(wú)法滿(mǎn)足了。這時(shí)候發(fā),我們可以通過(guò)使用@ApiOperation
注解中的tags
屬性做更細(xì)粒度的接口分類(lèi)定義,比如上面的需求就可以這樣子寫(xiě):
@Api(tags = {"教師管理","教學(xué)管理"})
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {
@ApiOperation(value = "xxx")
@GetMapping("/xxx")
public String xxx() {
return "xxx";
}
}
@Api(tags = {"學(xué)生管理"})
@RestController
@RequestMapping(value = "/student")
static class StudentController {
@ApiOperation(value = "獲取學(xué)生清單", tags = "教學(xué)管理")
@GetMapping("/list")
public String bbb() {
return "bbb";
}
@ApiOperation("獲取教某個(gè)學(xué)生的老師清單")
@GetMapping("/his-teachers")
public String ccc() {
return "ccc";
}
@ApiOperation("創(chuàng)建一個(gè)學(xué)生")
@PostMapping("/aaa")
public String aaa() {
return "aaa";
}
}
效果如下圖所示:
內(nèi)容的順序
在完成了接口分組之后,對(duì)于接口內(nèi)容的展現(xiàn)順序又是眾多用戶(hù)特別關(guān)注的點(diǎn),其中主要涉及三個(gè)方面:分組的排序、接口的排序以及參數(shù)的排序,下面我們就來(lái)逐個(gè)說(shuō)說(shuō)如何配置與使用。
一、分組的排序
關(guān)于分組排序,也就是Tag的排序。目前版本的Swagger支持并不太好,通過(guò)文檔我們可以找到關(guān)于Tag排序的配置方法。
第一種:原生Swagger用戶(hù),可以通過(guò)如下方式:
第二種:Swagger Starter用戶(hù),可以通過(guò)修改配置的方式:
swagger.ui-config.tags-sorter=alpha
似乎找到了希望,但是其實(shí)這塊并沒(méi)有什么可選項(xiàng),一看源碼便知:
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只提供了一個(gè)選項(xiàng),就是按字母順序排列。那么我們要如何實(shí)現(xiàn)排序呢?這里筆者給一個(gè)不需要擴(kuò)展源碼,僅依靠使用方式的定義來(lái)實(shí)現(xiàn)排序的建議:為T(mén)ag的命名做編號(hào)。比如:
@Api(tags = {"1-教師管理","3-教學(xué)管理"})
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {
// ...
}
@Api(tags = {"2-學(xué)生管理"})
@RestController
@RequestMapping(value = "/student")
static class StudentController {
@ApiOperation(value = "獲取學(xué)生清單", tags = "3-教學(xué)管理")
@GetMapping("/list")
public String bbb() {
return "bbb";
}
// ...
}
由于原本存在按字母排序的機(jī)制在,通過(guò)命名中增加數(shù)字來(lái)幫助排序,可以簡(jiǎn)單而粗暴的解決分組問(wèn)題,最后效果如下:
二、接口的排序
在完成了分組排序問(wèn)題(雖然不太優(yōu)雅...)之后,在來(lái)看看同一分組內(nèi)各個(gè)接口該如何實(shí)現(xiàn)排序。同樣的,凡事先查文檔,可以看到Swagger也提供了相應(yīng)的配置,下面也分兩種配置方式介紹:
第一種:原生Swagger用戶(hù),可以通過(guò)如下方式:
第二種:Swagger Starter用戶(hù),可以通過(guò)修改配置的方式:
swagger.ui-config.operations-sorter=alpha
很慶幸,這個(gè)配置不像Tag的排序配置沒(méi)有可選項(xiàng)。它提供了兩個(gè)配置項(xiàng):alpha和method,分別代表了按字母表排序以及按方法定義順序排序。當(dāng)我們不配置的時(shí)候,改配置默認(rèn)為alpha。兩種配置的效果對(duì)比如下圖所示:
三、參數(shù)的排序
完成了接口的排序之后,更細(xì)粒度的就是請(qǐng)求參數(shù)的排序了。默認(rèn)情況下,Swagger對(duì)Model參數(shù)內(nèi)容的展現(xiàn)也是按字母順序排列的。所以之前教程中的User對(duì)象在文章中展現(xiàn)如下:
如果我們希望可以按照Model中定義的成員變量順序來(lái)展現(xiàn),那么需要我們通過(guò)@ApiModelProperty注解的position參數(shù)來(lái)實(shí)現(xiàn)位置的設(shè)置,比如:
@Data
@ApiModel(description = "用戶(hù)實(shí)體")
public class User {
@ApiModelProperty(value = "用戶(hù)編號(hào)", position = 1)
private Long id;
@NotNull
@Size(min = 2, max = 5)
@ApiModelProperty(value = "用戶(hù)姓名", position = 2)
private String name;
@NotNull
@Max(100)
@Min(10)
@ApiModelProperty(value = "用戶(hù)年齡", position = 3)
private Integer age;
@NotNull
@Email
@ApiModelProperty(value = "用戶(hù)郵箱", position = 4)
private String email;
}
最終效果如下:
注:本文轉(zhuǎn)載自“程序猿DD”,如有侵權(quán),請(qǐng)聯(lián)系刪除!