本文屬于原創(chuàng)答倡,轉(zhuǎn)載注明出處莹桅,歡迎關(guān)注微信小程序小白AI博客
微信公眾號(hào)小白AI
或者網(wǎng)站 https://xiaobaiai.net
[TOC]
1 前言
在如今前后端分離開發(fā)的模式下,前端調(diào)用后端提供的API去實(shí)現(xiàn)數(shù)據(jù)的展示或者相關(guān)的數(shù)據(jù)操作恰梢,保證及時(shí)更新和完整的REST API文檔將會(huì)大大地提高兩邊的工作效率淤击,減少不必要的溝通成本晃酒。本文采用的Swagger2就是一個(gè)當(dāng)前流行的通過少量的注解就可以生成漂亮的API文檔工具,且在生成的在線文檔中提供類似POSTMAN直接調(diào)試能力隙咸,不僅僅是靜態(tài)的文檔沐悦。接下來將會(huì)利用這個(gè)工具與Spring Boot項(xiàng)目結(jié)合,最終生成我們上一篇文章中所涉及到的REST API文檔五督。
這一篇文章基本將Swagger2在生產(chǎn)環(huán)境中可能會(huì)用到的配置都有涉及藏否,慢慢看吧,看了這一篇因該是夠了充包。
2 Swagger2簡介
Swagger是與用于實(shí)現(xiàn) OpenAPI 文檔廣泛使用的工具副签,Swagger工具集包括開源工具遥椿,免費(fèi)工具和商業(yè)工具的組合,可在API生命周期的不同階段使用淆储。
-
Swagger Editor
(開源):使用Swagger編輯器冠场,可以在瀏覽器內(nèi)的YAML文檔中編輯OpenAPI規(guī)范并支持實(shí)時(shí)預(yù)覽文檔,可以參考官方的Demo https://editor.swagger.io/ -
Swagger UI
(開源):讓Swagger產(chǎn)生的文檔更漂亮本砰,而且支持API交互操作碴裙,在生成文檔后,直接在瀏覽器中瀏覽点额,并可以實(shí)現(xiàn)類似curl
命令或者postman
訪問我們的API,并返回相關(guān)數(shù)據(jù)。 -
Swagger Codegen
(開源): 是一個(gè)代碼生成器驻龟,可以通過Swagger API定義生成不同語言版本的服務(wù)端和客戶端工程代碼徽千。 -
Swagger Core
(開源):用于生成Swagger API規(guī)范的示例和服務(wù)器集成,可輕松訪問REST API珍手,結(jié)合Swagger UI
办铡,讓生成的文檔更漂亮。 -
Swagger Parser
(開源): Java開發(fā)珠十,解析OpenAPI定義的獨(dú)立庫 -
Swagger Inspector
(免費(fèi)):API在線測試工具料扰,驗(yàn)證API并從現(xiàn)有API生成OpenAPI定義功能 https://goo.gl/fZYHWz -
SwaggerHub
(免費(fèi)和商用版):API設(shè)計(jì)和文檔化,為使用OpenAPI的團(tuán)隊(duì)打造焙蹭。
3 開始使用
3.1 構(gòu)建Restful WEB服務(wù)
參考《Spring Boot從零入門5_五臟俱全的RESTful Web Service構(gòu)建》晒杈。構(gòu)建好后有如下REST API:
# 獲取所有用戶信息
GET http://localhost:8080/api/v1/users
# 新增一個(gè)用戶,參數(shù)通過body傳遞
POST http://localhost:8080/api/v1/users
# 更新一個(gè)用戶信息
PUT http://localhost:8080/api/v1/users/{id}
# 刪除指定用戶
DELETE http://localhost:8080/api/v1/users/{id}
3.2 集成Swagger2
構(gòu)建好RESTful WEB服務(wù)后孔厉,接下來我們集成Swagger拯钻,然后對(duì)上節(jié)中的REST API自動(dòng)生成接口文檔。
3.2.1 pom.xml添加依賴
集成Swagger2撰豺,需要在pom.xml中添加依賴源:
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<!-- 截至2019年11月7日為止粪般,最新版本為2.9.2 -->
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<version>2.9.2</version>
</dependency>
</dependencies>
3.2.2 Swagger 配置及初始化
springfox
有一個(gè)專用對(duì)象Docket,可以靈活的配置Swagger的各種屬性污桦,首先我們簡單的創(chuàng)建一個(gè)Swagger配置類Swagger2Config.java
:
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean("UsersApis")
public Docket usersApis() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
這里的@Configuration
注解用于定義配置類亩歹,被注解的類內(nèi)部包含有一個(gè)或多個(gè)被@Bean
注解的方法,這些方法將會(huì)被AnnotationConfigApplicationContext
類進(jìn)行掃描凡橱,并用于構(gòu)建Bean定義小作,初始化對(duì)象。@ComponentScan
會(huì)自動(dòng)獲取所有的Spring Components稼钩,包括@Configuration
類顾稀。另外這里的“用戶管理模塊”API生成配置很簡單,對(duì)所有路徑上API都去生成文檔坝撑。
3.2.3 啟動(dòng)服務(wù)并驗(yàn)證
當(dāng)完成Swagger2的配置類時(shí)静秆,啟動(dòng)WEB服務(wù)粮揉,通過http://localhost:8080/v2/api-docs就可以訪問生成文檔內(nèi)容,但是瀏覽器返回的是JSON內(nèi)容抚笔,基本上很難給需要用到相關(guān)API的開發(fā)人員進(jìn)行參考扶认。這個(gè)時(shí)候就需要用到Swagger2 UI
了。
3.3 集成Swagger2 UI
pom.xml添加依賴塔沃,然后重啟WEB服務(wù)就可以了蝠引,再次訪問http://localhost:8080/swagger-ui.html,這時(shí)候看到的就是WEB文檔了蛀柴。
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
從swagger-ui頁面看到的內(nèi)容有一部無關(guān)的內(nèi)容螃概,或者是如何明顯表現(xiàn)跟項(xiàng)目相關(guān)的內(nèi)容呢?下面章節(jié)詳細(xì)講解Swagger的各種配置鸽疾,能夠應(yīng)用到實(shí)際生產(chǎn)環(huán)境中去吊洼。
4 Swagger2 深度配置
4.1 深度配置目標(biāo)
首先,如果要將我們最后生成的API文檔給生產(chǎn)環(huán)境的開發(fā)人員查閱制肮,那么友好的展示信息和歸類是很有必要的冒窍,我們接下來實(shí)現(xiàn)如下目標(biāo):
- 文檔的各種信息說明
- 文檔標(biāo)題
- 文檔描述
- 文檔版本號(hào)
- Logo
- 文檔責(zé)任人
- 文檔許可證信息
- 文檔服務(wù)條款
- API分組
- 組描述
- 各API描述
- 附加部分(非API)
- 定制化文檔頁面風(fēng)格
為了更好地展示API分組功能,這里另外加了一組REST API (代碼層面上只需要將User相關(guān)的代碼全部復(fù)制一份豺鼻,將User關(guān)鍵字全部改為Product就可以了综液,包括大小寫):
# 獲取所有產(chǎn)品信息
GET http://localhost:8080/api/v1/products
# 新增一個(gè)產(chǎn)品,參數(shù)通過body傳遞
POST http://localhost:8080/api/v1/products
# 更新一個(gè)產(chǎn)品信息
PUT http://localhost:8080/api/v1/products/{id}
# 刪除指定產(chǎn)品
DELETE http://localhost:8080/api/v1/products/{id}
4.2 文檔信息配置
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean("UsersApis")
public Docket usersApis() {
return new Docket(DocumentationType.SWAGGER_2)
// select()返回的是ApiSelectorBuilder對(duì)象儒飒,而非Docket對(duì)象
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
// build()返回的是Docket對(duì)象
.build()
// 測試API時(shí)的主機(jī)URL
.host("https://xiaobaiai.net")
// API前綴
.pathProvider(new RelativePathProvider(null) {
@Override
public String getApplicationBasePath() {
return "/prefix";
}
})
.apiInfo(apiInfo());
}
public ApiInfo apiInfo() {
// API負(fù)責(zé)人的聯(lián)系信息
final Contact contact = new Contact(
"Ethan", "https://xiaobaiai.net", "ycm_hy@163.com");
return new ApiInfoBuilder()
// API文檔標(biāo)題
.title("X系統(tǒng)平臺(tái)接口文檔")
// API文檔描述
.description("用戶/產(chǎn)品相關(guān)API, 更多請(qǐng)關(guān)注公眾號(hào): 小白AI 或微信小程序:小白AI博客")
// 服務(wù)條款URL
.termsOfServiceUrl("https://github.com/yicm")
// API文檔版本
.version("1.0")
// API負(fù)責(zé)人的聯(lián)系信息
.contact(contact)
// API的許可證Url
.licenseUrl("http://license.coscl.org.cn/MulanPSL")
.license("MulanPSL")
.build();
}
}
通過添加文檔信息編譯對(duì)象ApiInfoBuilder
可以配置API文檔的各種信息谬莹,包括標(biāo)題、描述桩了、服務(wù)條款附帽、版本、責(zé)任人井誉、許可證等蕉扮。最后在Docket中添加信息配置對(duì)象即可生效。
4.3 API分組配置颗圣、API精細(xì)配置
4.3.1 API分組展示
上面的文檔信息配置中默認(rèn)是沒有對(duì)API分組的喳钟,即所有的API都展示在了一個(gè)頁面,沒有隔離在岂,如果需要分組荚藻,那我們需要對(duì)不同API組分配Bean,目前示例可以分為用戶API組和產(chǎn)品API組洁段,然后通過apis()
和 paths()
進(jìn)行API過濾。
為了不顯示某個(gè)包下面API或某個(gè)URL路徑下API共郭, Docket
提供了 apis()
和 paths()
兩 個(gè)方法來幫助我們?cè)诓煌?jí)別上過濾接口(上面示例我們默認(rèn)對(duì)這兩個(gè)設(shè)置是不做任何過濾祠丝,掃描所有API):
-
apis()
:這種方式可以通過指定包名的方式疾呻,讓 Swagger2 只去某些包下面掃描 -
paths()
:這種方式可以通過篩選 API 的 URL 來進(jìn)行過濾
apis和paths中的Predicates
除了any
、ant
写半、none
岸蜗,還支持regex
正則表達(dá)式。
如:
PathSelectors.regex("/api/v2/users.*")
下面就是分組示例代碼叠蝇,實(shí)現(xiàn)分組璃岳,很簡單,就是在Docket中配置組名就好了:
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket usersApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用戶管理接口")
// select()返回的是ApiSelectorBuilder對(duì)象悔捶,而非Docket對(duì)象
.select()
.apis(RequestHandlerSelectors.basePackage("com.xiaobaiai.user"))
.paths(Predicates.or(
// 兩個(gè)**铃慷,可以匹配底下所有URL
// 一個(gè)*,只能匹配一級(jí)URL分段
PathSelectors.ant("/api/v1/users/**"),
PathSelectors.ant("/api/v1/users/*")))
// build()返回的是Docket對(duì)象
.build()
// 測試API時(shí)的主機(jī)URL
.host("https://xiaobaiai.net")
// API前綴蜕该,最終所有API的基礎(chǔ)地址就是host+prefix: https://xiaobaiai.net/prefix
.pathProvider(new RelativePathProvider(null) {
@Override
public String getApplicationBasePath() {
return "/prefix";
}
})
.apiInfo(apiInfo());
}
@Bean
public Docket productsApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("產(chǎn)品管理接口")
// select()返回的是ApiSelectorBuilder對(duì)象犁柜,而非Docket對(duì)象
.select()
.apis(RequestHandlerSelectors.basePackage("com.xiaobaiai.product"))
.paths(Predicates.or(
// 兩個(gè)**,可以匹配底下所有URL
// 一個(gè)*堂淡,只能匹配一級(jí)URL分段
PathSelectors.ant("/api/v1/products/**"),
PathSelectors.ant("/api/v1/products/*")))
// build()返回的是Docket對(duì)象
.build()
// 測試API時(shí)的主機(jī)URL
.host("https://xiaobaiai.net")
// API前綴
.pathProvider(new RelativePathProvider(null) {
@Override
public String getApplicationBasePath() {
return "/prefix";
}
})
.apiInfo(apiInfo());
}
public ApiInfo apiInfo() {
// API負(fù)責(zé)人的聯(lián)系信息
final Contact contact = new Contact(
"Ethan", "https://xiaobaiai.net", "ycm_hy@163.com");
return new ApiInfoBuilder()
// API文檔標(biāo)題
.title("X系統(tǒng)平臺(tái)接口文檔")
// API文檔描述
.description("用戶/產(chǎn)品相關(guān)API, 更多請(qǐng)關(guān)注公眾號(hào): 小白AI 或微信小程序:小白AI博客")
// 服務(wù)條款URL
.termsOfServiceUrl("https://github.com/yicm")
// API文檔版本
.version("1.0")
// API負(fù)責(zé)人的聯(lián)系信息
.contact(contact)
// API的許可證Url
.licenseUrl("http://license.coscl.org.cn/MulanPSL")
.license("MulanPSL")
.build();
}
}
分組配置完成后馋缅,重新啟動(dòng),打開瀏覽器就可以看到效果了:
4.3.2 API精細(xì)配置
雖然上面我們已經(jīng)可以控制API的顯示和分組了绢淀,但是對(duì)于API一些更詳細(xì)萤悴,對(duì)組內(nèi)API再次歸類之類的,比如小組的描述信息皆的,以及每個(gè)API如何去控制它的參數(shù)說明覆履,返回值說明等。這些都是通過注解去實(shí)現(xiàn)的祭务,接下來我們講述常用的注解及作用:
-
@Api
: 將這個(gè)注解添加到控制器類上内狗,則可以給控制器添加描述類信息:
相關(guān)可設(shè)置參數(shù)有:
- value: 用作承載資源的API聲明的“路徑”,可以說是API URL的別名
- tags:如果設(shè)置這個(gè)值义锥、value的值會(huì)被覆蓋
- description:已過時(shí)柳沙,對(duì)api資源的描述
- protocols:協(xié)議類型如: http, https, ws, wss.
- hidden:配置為true ,隱藏此資源下的操作(試驗(yàn)了下拌倍,貌似無法生效赂鲤,替代方案還是用@ApiIgnore吧)
- produces:如 “application/json, application/xml”
- consumes: 如 “application/json, application/xml”
- authorizations:高級(jí)特性認(rèn)證時(shí)配置
示例:
// Swagger配置類
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket productsApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("產(chǎn)品管理接口")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xiaobaiai.product"))
.paths(Predicates.or(
PathSelectors.ant("/api/v1/products/**"),
PathSelectors.ant("/api/v1/products/*")))
.build()
.host("https://xiaobaiai.net")
.pathProvider(new RelativePathProvider(null) {
@Override
public String getApplicationBasePath() {
return "/prefix";
}
})
.apiInfo(apiInfo())
.tags(new Tag("產(chǎn)品操作分組1", "產(chǎn)品查詢相關(guān)操作."),
new Tag("產(chǎn)品操作分組2", "產(chǎn)品添加或刪除相關(guān)操作."),
new Tag("產(chǎn)品操作分組3", "產(chǎn)品更新相關(guān)操作."),
new Tag("產(chǎn)品操作分組4", "產(chǎn)品相關(guān)全部操作."));
}
}
// 控制器類
@RestController
@RequestMapping("/api/v1")
@Api(tags={"產(chǎn)品接口文檔列表"})
public class ProductServiceController { ... }
效果如下:
-
@ApiIgnore
: 作用在REST API控制器方法
上,則該API不會(huì)被顯示出來:
@ApiIgnore
@RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Object> delete(@PathVariable("id") String id) { ... }
-
@ApiOperation
注解用于控制器方法
上面柱恤,用于對(duì)方法的描述数初,相關(guān)參數(shù)設(shè)置描述如下:
- value:接口的名稱
- notes:接口注意點(diǎn)說明
- response: 接口的返回類型,比如說:response = String.class
- hidden: 配置為true 將在文檔中隱藏
示例:
@ApiOperation(value = "獲取所有產(chǎn)品", notes = "每調(diào)用一次梗顺,就耗費(fèi)流量100M", response = String.class)
@GetMapping(value = "/products")
public ResponseEntity<Object> getProduct() {
return new ResponseEntity<>(productService.getProducts(), HttpStatus.OK);
}
最后效果就是:
-
@ApiImplicitParams
和@ApiImplicitParam
注解用于控制器方法傳入?yún)?shù)的說明泡孩。默認(rèn)情況下,Swagger會(huì)根據(jù)API方法中的傳入?yún)?shù)進(jìn)行參數(shù)說明的生成寺谤,不過參數(shù)說明默認(rèn)就是變量名仑鸥,因?yàn)檫@兩個(gè)注解不一定需要吮播。相關(guān)參數(shù)設(shè)置說明如下:
- name:參數(shù)名稱,注意一定要與實(shí)際方法的形參名一致眼俊,否則無法生效
- value:參數(shù)值
- defaultValue:參數(shù)默認(rèn)值
- required:是否為必需項(xiàng)
- allowMultiple: 是否允許重復(fù)
- dataType: 數(shù)據(jù)類型意狠,如object,string,array,int,等
- paramType:參數(shù)傳遞類型
- header : 放在請(qǐng)求頭。請(qǐng)求參數(shù)的獲却帧:
@RequestHeader
(代碼中接收注解) - query : 用于get請(qǐng)求的參數(shù)拼接环戈。請(qǐng)求參數(shù)的獲取:
@RequestParam
(代碼中接收注解) - path : 用于restful接口澎灸,請(qǐng)求參數(shù)的獲仍喝:
@PathVariable
(代碼中接收注解) - body : 放在請(qǐng)求體。請(qǐng)求參數(shù)的獲然骱ⅰ:
@RequestBody
(代碼中接收注解) - form : 不常用
- header : 放在請(qǐng)求頭。請(qǐng)求參數(shù)的獲却帧:
- examples: 示例
示例:
// 如果只有一個(gè)參數(shù)迫悠,則僅僅@ApiImplicitParam就可以了
@ApiImplicitParams({
@ApiImplicitParam(name="id", value="產(chǎn)品ID值", required = true),
@ApiImplicitParam(name="product", value="產(chǎn)品內(nèi)容", required = true)
})
@RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Product product) {
productService.updateProduct(id, product);
return new ResponseEntity<>("Product is updated successsfully", HttpStatus.OK);
}
-
@ApiParam
: 作用同ApiImplicitParam,單個(gè)參數(shù)描述一般常用該注解巩梢,而且該注解只能與JAX-RS 1.x/2.x注解結(jié)合使用创泄。參數(shù)設(shè)置說明如下:
- name: 參數(shù)名稱
- value: 參數(shù)值
- required: 是否為必須項(xiàng)
- defaultValue: 默認(rèn)值
- type: 參數(shù)類型
- hidden: 是否因此該參數(shù)
-
@ApiResponses
、@ApiResponse
: 用于控制器方法返回值的說明括蝠,參數(shù)設(shè)置說明如下:
- code: http的狀態(tài)碼
- message:返回狀態(tài)描述
- response: 狀態(tài)響應(yīng)鞠抑,默認(rèn)響應(yīng)類為Void
示例:
@ApiOperation(value = "獲取所有產(chǎn)品", notes = "每調(diào)用一次,就耗費(fèi)流量100M",response =Product.class, responseContainer="List")
@ApiResponses({
@ApiResponse(code = 200, message = "成功忌警!", response=Product.class),
@ApiResponse(code = 401, message = "未授權(quán)搁拙!", response=Product.class),
@ApiResponse(code = 404, message = "頁面未找到!", response=Product.class),
@ApiResponse(code = 403, message = "出錯(cuò)了法绵!", response=Product.class)
})
@GetMapping(value = "/products")
public ResponseEntity<Object> getProduct() {
return new ResponseEntity<>(productService.getProducts(), HttpStatus.OK);
}
效果如下:
@Deprecated
: 作用于控制器方法上箕速,標(biāo)注該方法已經(jīng)過時(shí),建議開發(fā)者采用新的方式之類的朋譬。@ApiModel
:作用在JavaBean類上盐茎,說明JavaBean的用途,如我們定義的Product.java類徙赢。常用參數(shù)設(shè)置如下:
- value: 實(shí)體類別名字柠,默認(rèn)為類名字
- description: 描述
- parent: 父類,默認(rèn)為Void.class
- subTypes: 默認(rèn)為{}
- reference: 依賴狡赐,默認(rèn)為""
示例:
@ApiModel(value="Product",description="對(duì)產(chǎn)品定義的描述")
public class Product { ... }
-
@ApiModelProperty
: 同樣用于在JavaBean類的屬性上面窑业,說明相關(guān)屬性。類似于方法上說明的@ApiImplicitParam
枕屉。設(shè)置參數(shù)有:
- name: 屬性名稱常柄,需與JavaBean內(nèi)保持一致
- value: 屬性值
- notes: 說明
- dataType: 數(shù)據(jù)類型
- required: 是否必須
- readOnly: 是否只讀,默認(rèn)為false
- reference: 依賴,默認(rèn)為""
- allowEmptyValue: 是否允許空值
- allowableValues: 允許值西潘,默認(rèn)為""
4.4 API歷史版本管理
管理不同API版本有好幾種方式:
- 通過URL的方式铜异,將版本號(hào)包含在URL中,如
/api/v1/users
秸架。通過這種方式,我們可以在Docket中過濾出不同版本咆蒿,結(jié)合分組东抹,可以實(shí)現(xiàn)不同版本的API管理。 - 通過查詢參數(shù)沃测,將版本號(hào)作為一個(gè)具體參數(shù)缭黔,如
/api/users?version=1
- 通過自定義HTTP頭–定義一個(gè)新的頭,其中包含請(qǐng)求中的版本號(hào)
- 通過內(nèi)容(Content)協(xié)商:版本號(hào)與接受的內(nèi)容類型一起包含在“Accept”頭中蒂破,如
curl -H "Accept: application/vnd.piomin.v1+json" http://localhost:8080/api/users
這里我們對(duì)第一種方式示例展示:
在Swagger2Config.java中新添加一個(gè)用戶API Docket:
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean("UsersApis_V1")
public Docket usersApisV1() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用戶管理接口V1")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xiaobaiai.user"))
.paths(Predicates.or(
// 過濾版本v1
PathSelectors.ant("/api/v1/users/**"),
PathSelectors.ant("/api/v1/users/*")))
.build()
.host("https://xiaobaiai.net")
.pathProvider(new RelativePathProvider(null) {
@Override
public String getApplicationBasePath() {
return "/prefix";
}
})
.apiInfo(apiInfo());
}
@Bean("UsersApis_V21")
public Docket usersApisV2() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用戶管理接口V2")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xiaobaiai.user"))
.paths(Predicates.or(
// 過濾版本v1
PathSelectors.ant("/api/v2/users/**"),
PathSelectors.ant("/api/v2/users/*")))
.build()
.host("https://xiaobaiai.net")
.pathProvider(new RelativePathProvider(null) {
@Override
public String getApplicationBasePath() {
return "/prefix";
}
})
.apiInfo(apiInfo());
}
@Bean
public Docket productsApis() {
return new Docket(DocumentationType.SWAGGER_2)
.....
}
public ApiInfo apiInfo() {
final Contact contact = new Contact(
"Ethan", "https://xiaobaiai.net", "ycm_hy@163.com");
return new ApiInfoBuilder()
.title("X系統(tǒng)平臺(tái)接口文檔")
.description("用戶/產(chǎn)品相關(guān)API, 更多請(qǐng)關(guān)注公眾號(hào): 小白AI 或微信小程序:小白AI博客")
.termsOfServiceUrl("https://github.com/yicm")
.version("1.0")
.contact(contact)
.licenseUrl("http://license.coscl.org.cn/MulanPSL")
.license("MulanPSL")
.build();
}
}
然后控制器添加新版本API方法:
@RestController
@RequestMapping("/api")
public class UserServiceController {
@Autowired
UserService userService;
@DeleteMapping({"/v1/users/{id}", "/v2/users/{id}"})
public ResponseEntity<Object> delete(@PathVariable("id") String id) {
userService.deleteUser(id);
return new ResponseEntity<>("User is deleted successsfully", HttpStatus.OK);
}
@PutMapping({"/v1/users/{id}", "/v2/users/{id}"})
public ResponseEntity<Object> updateUser(@PathVariable("id") String id, @RequestBody User user) {
userService.updateUser(id, user);
return new ResponseEntity<>("User is updated successsfully", HttpStatus.OK);
}
@PostMapping({"/v1/users", "/v2/users"})
public ResponseEntity<Object> createUser(@RequestBody User user) {
userService.createUser(user);
return new ResponseEntity<>("User is created successfully", HttpStatus.CREATED);
}
@GetMapping({"/v1/users"})
@Deprecated
public ResponseEntity<Object> getUser() {
return new ResponseEntity<>(userService.getUsers(), HttpStatus.OK);
}
@GetMapping(value = "/v2/users")
public ResponseEntity<Object> getUser(@RequestParam String id) {
return new ResponseEntity<>(userService.getUsers(), HttpStatus.OK);
}
}
最后效果:
其他的方式類似也差不多馏谨,如在Header中區(qū)分版本,這里就不展開了附迷。
4.5 其他配置
4.5.1 為每個(gè)API配置全局Token實(shí)現(xiàn)一次性授權(quán)
當(dāng)我們的REST API加入的授權(quán)機(jī)制時(shí)惧互,即需具有對(duì)該API的訪問權(quán)限,才能夠操作該API喇伯,但是我們想在Swagger UI中去調(diào)試API喊儡,那么如何解決每個(gè)API一次性授權(quán),全部API可訪問呢稻据?增加使用的方便性艾猜,不用每次都對(duì)每個(gè)API進(jìn)行授權(quán)。不過需要在WEB服務(wù)中已經(jīng)使用了API授權(quán)機(jī)制才會(huì)需要這項(xiàng)配置捻悯。這里暫不展開匆赃,后面單獨(dú)講述Spring Security
+ Swagger2 UI
配置。
4.5.2 在線文檔頁面中更換語言
應(yīng)該是不能的: https://github.com/swagger-api/swagger-ui#known-issues
- translations is not implemented.
5 總結(jié)
這一篇從介紹Swagger2入手今缚,講述在Spring Boot中如何集成和配置Swagger2算柳,并生成生成環(huán)境中的在線API文檔,包括如何將API分組荚斯,組信息描述埠居,API信息描述,API方法參數(shù)描述事期,如果對(duì)API版本進(jìn)行管理等滥壕,最后還擴(kuò)展了內(nèi)容,包括如何為每個(gè)API配置全局Token等兽泣。內(nèi)容很全绎橘,參考這一篇應(yīng)該是夠了,繼續(xù)!
6 參考文檔
- https://swagger.io/blog/api-strategy/difference-between-swagger-and-openapi/
- https://swagger.io/tools/swagger-editor/
- https://editor.swagger.io/
- https://swagger.io/swagger-ui/
- https://github.com/swagger-api/swagger-parser
- https://github.com/swagger-api/swagger-codegen
- http://springfox.github.io/springfox/javadoc/2.9.2/springfox/documentation/builders/package-summary.html
- http://springfox.github.io/springfox/javadoc/2.9.2/springfox/documentation/service/package-summary.html
- http://springfox.github.io/springfox/javadoc/2.9.2/index.html?springfox/documentation/spring/web/plugins/Docket.html
- http://www.reibang.com/p/6e5ee9dd5a61 加入全局參數(shù)
- http://docs.swagger.io/swagger-core/current/apidocs/io/swagger/annotations/ApiParam.html
- https://stackoverflow.com/questions/53615700/how-set-springfox-to-show-two-or-more-versions-of-the-rest-api-using-spring-bo2
- https://piotrminkowski.wordpress.com/2018/02/19/versioning-rest-api-with-spring-boot-and-swagger/
- https://stackoverflow.com/questions/37671125/how-to-configure-spring-security-to-allow-swagger-url-to-be-accessed-without-aut/37683455
- https://swagger.io/docs/specification/authentication/basic-authentication/
本文屬于原創(chuàng)称鳞,轉(zhuǎn)載注明出處涮较,歡迎關(guān)注CSDNfreeape或微信小程序小白AI博客
微信公眾號(hào)小白AI
或者網(wǎng)站 https://xiaobaiai.net