Spring Boot 集成 Swagger 生成 RESTful API 文档
原文鏈接:
- Spring Boot 集成 Swagger 生成 RESTful API 文檔
簡(jiǎn)介
Swagger 官網(wǎng)是這么描述它的:The Best APIs are Built with Swagger Tools。
Swagger 是一套基于 OpenAPI 規(guī)范構(gòu)建的開(kāi)源工具,可以幫助我們?cè)O(shè)計(jì)、構(gòu)建、記錄以及使用 Rest API。Swagger 主要包含了以下三個(gè)部分:
Spring Boot 使得開(kāi)發(fā) RESTful 服務(wù)變得簡(jiǎn)單。那么編寫 Spring Boot 接口,為何要用 Swagger 呢?
- 代碼改變,文檔就會(huì)改變。只需要少量的注釋,Swagger 就可以根據(jù)代碼自動(dòng)生成 API 文檔。
- Swagger UI 是一份交互式的 API 文檔,可以直接在 Web 界面調(diào)用 API。這里有一份 Swagger UI 的 Live Demo,看看官方是怎么寫 RESTful API 的。
添加依賴
pom.xml 引入 Swagger 相關(guān)的依賴:
<!-- swagger2 --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger.version}</version> </dependency> <!-- swagger2 ui --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.version}</version> </dependency>使用 property 定義了 Swagger 的版本,因此還需要添加:
<swagger.version>2.9.2</swagger.version>依賴說(shuō)明:
- springfox-swagger2 Swagger 的 Java 實(shí)現(xiàn)
- springfox-swagger-ui Swagger UI 頁(yè)面的依賴
Swagger 配置類
使用注解 @Configuration 編寫 Swagger 配置類—— SwaggerConfig。
新建 config 的包,創(chuàng)建 SwaggerConifg 的配置類:
//通過(guò)@Configuration注解,讓Spring來(lái)加載該類配置 @Configuration //通過(guò)@EnableSwagger2注解來(lái)啟用Swagger2 @EnableSwagger2 //@ConditionalOnExpression 為Spring的注解,用戶是否實(shí)例化本類,用于是否啟用Swagger的判斷(生產(chǎn)環(huán)境需要屏蔽Swagger) @ConditionalOnExpression("${swagger.enable:true}") public class SwaggerConfig {// select()函數(shù)返回一個(gè)ApiSelectorBuilder實(shí)例用來(lái)控制哪些接口暴露給Swagger來(lái)展現(xiàn),本例采用指定掃描的包路徑來(lái)定義,// Swagger會(huì)掃描該包下所有Controller定義的API,并產(chǎn)生文檔內(nèi)容(除了被@ApiIgnore指定的請(qǐng)求)@Beanpublic Docket createRestApi() {// apiInfo()用來(lái)創(chuàng)建該Api的基本信息(這些基本信息會(huì)展現(xiàn)在文檔頁(yè)面中ApiInfo apiInfo = new ApiInfoBuilder().title("標(biāo)題: Spring Boot 項(xiàng)目集成 Swagger 示例文檔").description("描述: 我的博客地址是 https://michael728.github.io").termsOfServiceUrl("https://michael728.github.io/").version("1.0").build();Docket docket = new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo)// select()函數(shù)返回一個(gè)ApiSelectorBuilder實(shí)例.select()// 決定了暴露哪些接口給 Swagger.paths(regex("/api/.*")).build().useDefaultResponseMessages(false).gloreturn docket;} }說(shuō)明:
- @Configuration 是告訴 Spring Boot 需要加載這個(gè)配置類;
- @EnableSwagger2 是啟用 Swagger2,沒(méi)加的話,就看不到效果了;
- ApiInfo 對(duì)象用來(lái)設(shè)置一些文檔的版本號(hào)、聯(lián)系人郵箱、網(wǎng)站、版權(quán)、開(kāi)源協(xié)議等等信息(這些基本信息會(huì)展現(xiàn)在文檔頁(yè)面中)。并使用 Docket.apiInfo() 方法來(lái)設(shè)置;
- Docket 上增加篩選。提供了 apis() 和 paths() 兩個(gè)方法幫助我們?cè)诓煌?jí)別上過(guò)濾接口:
- apis() 這種方式我們可以指定包名的方式,讓 Swagger 只去某些包下面掃描;
- paths() 這種方式可以通過(guò)篩選 API 的 url 來(lái)進(jìn)行篩選;
- @ConditionalOnExpression("${swagger.enable:true}") 這個(gè)注解控制了是否啟用 Swagger,我們需要在 appplication.properties 中加上 swagger.enable=true
編寫控制器類——Controller 類
我們先介紹一下在用 Swagger 時(shí)的常用注解:
- @API 類的注解,可以給控制器增加描述和標(biāo)簽信息。用在請(qǐng)求的類上,代表了這個(gè)類是 Swagger 的資源
- tags:控制器標(biāo)簽,對(duì)該類進(jìn)行「分類」,參數(shù)是個(gè)字符串?dāng)?shù)組,如果配置了多個(gè)值,會(huì)在多個(gè)分類中看到;
- value:該參數(shù)沒(méi)什么意義,在 UI 界面上并不顯示,可不用配置
- @ApiModel 類注解,對(duì) API 涉及的對(duì)象做描述,可用于響應(yīng)實(shí)體類,說(shuō)明實(shí)體作用
- value Model 展示時(shí)的名稱,默認(rèn)是 實(shí)體類的名稱,比如 UserEntity;
- description 實(shí)體類的描述
類成員變量的的注解:
- @ApiModelProperty 用在實(shí)體類的屬性上
- value 屬性字段描述;
- required 參數(shù)是否必選;
- name 重寫字段名稱;
- dataType 重寫字段類型;
- allowEmptyValue 是否允許為空;
- allowbleValues 該字段允許的值。當(dāng)我們 API 某個(gè)參數(shù)為枚舉類型時(shí),使用這個(gè)參數(shù)就可以清楚高速 API 使用者能允許傳入的值
方法的注解:
- @ApiOperation 描述方法的用途,用來(lái)展開(kāi)對(duì)接口的描述
- value 接口簡(jiǎn)要描述;
- notes 接口發(fā)布說(shuō)明,詳細(xì)描述;
- @ApiImplicitParams 用于描述接口的非對(duì)象參數(shù)集,一般與 @ApiImplicitParams 組合使用
- @ApiImplicitParam 描述參數(shù)信息
- value 參數(shù)意義的描述
- name 參數(shù)名字;
- required 默認(rèn) false,參數(shù)是否必傳
- dataType 參數(shù)數(shù)據(jù)類型,只作為標(biāo)志說(shuō)明,并沒(méi)有實(shí)際驗(yàn)證
- Long
- String
- paramType 參數(shù)類型,表示參數(shù)放在哪里
- query,默認(rèn)值,Query String 的方式傳參,請(qǐng)求參數(shù)的獲取:@RequestParam
- path 路徑參數(shù),請(qǐng)求參數(shù)的獲取:@PathVariable
- header 請(qǐng)求參數(shù)的獲取:@RequestHeader
- @PathVariable 路徑參數(shù),給類似 @GetMappIng("/user/{id}") 參數(shù)通過(guò)路徑傳入
其他:
- @ApiIgnore:用于類或者方法上,屏蔽接口不被顯示在頁(yè)面上;
- @Profile({"dev","test"}):用于配置類上,表示對(duì)什么環(huán)境啟用;
- @ApiParam 不能直接用在方法上,而是用在方法的形參定義中,下文會(huì)有示例;
實(shí)體類示例:
@Data @ApiModel(value = "用戶實(shí)體") public class UserEntity {public static final long serialVersionUID = 1L;@ApiModelProperty(value = "用戶 id")private int id;@ApiModelProperty(value = "用戶名", required = true)private String userName;@ApiModelProperty(value = "密碼" )private String passWord;@ApiModelProperty(value = "性別")private UserSexEnum userSex;@ApiModelProperty(value = "昵稱" )private String nickName;public UserEntity(Integer id, String userName, String passWord) {this.id = id;this.userName = userName;this.passWord = passWord;} }下面是一個(gè)控制類的示例:
@RestController @RequestMapping("/api/v1/") @Api(tags = {"用戶相關(guān)接口"}, value = "用戶模塊") public class UserController {// 模擬數(shù)據(jù)庫(kù)public static List<UserEntity> users = new ArrayList<>();static {UserEntity user1 = new UserEntity(1, "michael", "123");UserEntity user2 = new UserEntity(2, "qq", "123");UserEntity user3 = new UserEntity(3, "hh", "123");users.add(user1);users.add(user2);users.add(user3);}@ApiOperation(value = "獲取用戶列表", notes = "獲取全部用戶信息")@RequestMapping(value = "/users", method = RequestMethod.GET)public List<UserEntity> getUsers() {return users;}@ApiOperation(value = "查詢單用戶", notes = "根據(jù)用戶id 查詢其信息")@ApiImplicitParam(name = "id", value = "用戶id", paramType = "query", required = true)@GetMapping("/user/{id}")public UserEntity getUser(@PathParam("id") int id) {UserEntity user = users.get(id);return user;}@ApiOperation(value = "存儲(chǔ)用戶信息", notes = "存儲(chǔ)用戶詳細(xì)信息")@RequestMapping(value = "/user", method = RequestMethod.POST)public UserEntity saveUser(@ApiParam(value = "用戶信息", required = true)@RequestBody UserEntity user) {users.add(user);return user;}@ApiOperation(value = "刪除用戶", notes = "根據(jù)用戶id刪除用戶信息")@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "用戶id", required = true, paramType = "path")})@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)public int deleteUser(@PathVariable("id") int id) {users.remove(id);return id;}@ApiOperation(value = "更新用戶信息", notes = "更新用戶的個(gè)人信息")@PutMapping("/user/")public UserEntity updateUser(@RequestBody UserEntity user) {int id = user.getId();UserEntity oldUser = users.get(id);users.set(id, user);return user;} }啟動(dòng)
啟動(dòng)應(yīng)用,訪問(wèn) localhost:8080/swagger-ui.html 可以訪問(wèn)到 Swagger UI,可以點(diǎn)擊 Try it out 按鈕,調(diào)用 API:
頁(yè)面上還會(huì)有一個(gè) Models 的分類。Swagger UI 會(huì)根據(jù)我們?cè)趯?shí)體上使用的 @ApiModel 和 @ApiModelProperty 注解來(lái)自動(dòng)補(bǔ)充實(shí)體以及其屬性的描述和備注。
示例代碼
- awesome-spring-boot-examples
One More Thing
Web API 的風(fēng)格
開(kāi)發(fā) API,先了解一下有哪些 Web API 的風(fēng)格吧:
- RPC:RPC 面向過(guò)程,RPC 形式的 API 組織形態(tài)是類和方法,API 的命名往往是一個(gè)動(dòng)詞,比如 GetUserInfo,CreateUser;
- REST:REST 面向資源,也是下文將要介紹的一種 API 風(fēng)格;
- GraphQL:就是面向數(shù)據(jù)查詢,采用GraphQL,甚至不需要有任何的接口文檔,在定義了Schema之后,服務(wù)端實(shí)現(xiàn)Schema,客戶端可以查看Schema,然后構(gòu)建出自己需要的查詢請(qǐng)求來(lái)獲得自己需要的數(shù)據(jù)
REST
上文提到了 RESTful API 的概念,我覺(jué)得,不如趁機(jī)了解一下。因?yàn)樵趯?shí)際的項(xiàng)目中發(fā)現(xiàn),并不是每個(gè) Spring Boot 的開(kāi)發(fā)人員都能意識(shí)到開(kāi)發(fā)的 API 要盡量符合 RESTful 規(guī)則的。REST 實(shí)際上只是一種設(shè)計(jì)風(fēng)格,它并不是標(biāo)準(zhǔn)。
術(shù)語(yǔ):
- Endpoint 終點(diǎn),可以理解為路徑,表示 API 的具體網(wǎng)址。
- API(Application Programming Interface),應(yīng)用程序編程接口
- REST 是 Representational State Transfer 的縮寫。如果一個(gè)架構(gòu)符合 REST 原則,就稱它為 RESTful 架構(gòu)。RESTful API 就是 REST 風(fēng)格的 API
- Resource:資源,即數(shù)據(jù)。
- Representational:某種表現(xiàn)形式,比如用 JSON,XML,JPEG 等;
- State Transfer:狀態(tài)變化。通過(guò) HTTP 動(dòng)詞實(shí)現(xiàn)
在 RESTful 架構(gòu)中,每個(gè)網(wǎng)址代表一種資源(resource),所以網(wǎng)址中不能有動(dòng)詞,只能有名詞,而且所用的名詞往往與數(shù)據(jù)庫(kù)的表格名對(duì)應(yīng)。
資源的操作
RESTful 的核心思想就是,客戶端發(fā)出的數(shù)據(jù)操作指令都是"動(dòng)詞 + 賓語(yǔ)"的結(jié)構(gòu)。比如,GET /articles 這個(gè)命令,GET 是動(dòng)詞,/articles 是賓語(yǔ)。
對(duì)于資源的具體操作類型,由 HTTP 動(dòng)詞表示(括號(hào)里是對(duì)應(yīng)的 SQL 命令):
- GET(SELECT):從服務(wù)器取出資源(一項(xiàng)或多項(xiàng))。
- POST(CREATE):在服務(wù)器新建一個(gè)資源。
- PUT(UPDATE):在服務(wù)器更新資源(客戶端提供改變后的完整資源)。
- PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供改變的屬性)。
- DELETE(DELETE):從服務(wù)器刪除資源
還有兩個(gè)不常用的 HTTP 動(dòng)詞:
- HEAD:獲取資源的元數(shù)據(jù)。
- OPTIONS:獲取信息,關(guān)于資源的哪些屬性是客戶端可以改變的
知乎上的一個(gè)回答,我覺(jué)得很精辟:
- 看 Url 就知道要什么
- 看 http method 就知道干什么
- 看 http status code 就知道結(jié)果如何
一位答主給出的示例:
GET /rest/api/getDogs --> GET /rest/api/dogs 獲取所有小狗狗 GET /rest/api/addDogs --> POST /rest/api/dogs 添加一個(gè)小狗狗 GET /rest/api/editDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一個(gè)小狗狗 GET /rest/api/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 刪除一個(gè)小狗狗信息過(guò)濾 Filtering
如果記錄數(shù)量很多,服務(wù)器不可能都將它們返回給用戶。API 應(yīng)該提供參數(shù),過(guò)濾返回結(jié)果
- ?limit=10:指定返回記錄的數(shù)量
- ?offset=10:指定返回記錄的開(kāi)始位置。
- ?page=2&per_page=100:指定第幾頁(yè),以及每頁(yè)的記錄數(shù)
參考
- CSDN-Spring Boot集成Swagger
- 官宣-Swagger
- IBM-在 Spring Boot 項(xiàng)目中使用 Swagger 文檔
- 蜻蜓HTTP-springboot 集成完整的swagger2
API 介紹
- 阮一峰-RESTful API 設(shè)計(jì)指南
- 阮一峰-RESTful API 最佳實(shí)踐
- segmentfault-Philipp Hauer-[譯]RESTful API 設(shè)計(jì)最佳實(shí)踐 推薦
- RESTful Service API 設(shè)計(jì)最佳工程實(shí)踐和常見(jiàn)問(wèn)題解決方案 總結(jié)的相當(dāng)好,博客值得閱讀
- 華為云-API設(shè)計(jì)中關(guān)于RPC和REST 兩種風(fēng)格選擇的個(gè)人理解
- 跟著 Github 學(xué)習(xí) Restful HTTP API 設(shè)計(jì)
- 梁桂釗——人人都是 API 設(shè)計(jì)師:我對(duì) RESTful API、GraphQL、RPC API 的思考 作者分享了一些阿里團(tuán)隊(duì)里做法
- 阿里研究員谷樸:API 設(shè)計(jì)最佳實(shí)踐的思考
- 朱曄的互聯(lián)網(wǎng)架構(gòu)實(shí)踐心得S2E5:淺談四種API設(shè)計(jì)風(fēng)格(RPC、REST、GraphQL、服務(wù)端驅(qū)動(dòng))
歡迎關(guān)注個(gè)人公眾號(hào) 「iPlayMichael」
轉(zhuǎn)載于:https://www.cnblogs.com/michael-xiang/p/11216862.html
總結(jié)
以上是生活随笔為你收集整理的Spring Boot 集成 Swagger 生成 RESTful API 文档的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 对于变态数据搜索的心得
- 下一篇: Spring Boot 实战 —— My