簡(jiǎn)介
Swagger 是最流行的 API 開發(fā)工具,它遵循 OpenAPI Specification(OpenAPI 規(guī)范,也簡(jiǎn)稱 OAS)。
Swagger 可以貫穿于整個(gè) API 生態(tài),如 API 的設(shè)計(jì)、編寫 API 文檔、測(cè)試和部署。
Swagger 是一種通用的,和編程語(yǔ)言無(wú)關(guān)的 API 描述規(guī)范。
應(yīng)用場(chǎng)景
- 如果你的 RESTful API 接口都開發(fā)完成了,你可以用 Swagger-editor 來(lái)編寫 API 文檔( yaml 文件 或 json 文件),然后通過(guò) Swagger-ui 來(lái)渲染該文件,以非常美觀的形式將你的 API 文檔,展現(xiàn)給你的團(tuán)隊(duì)或者客戶。
- 如果你的 RESTful API 還未開始,也可以使用 Swagger ,來(lái)設(shè)計(jì)和規(guī)范你的 API,以 Annotation (注解)的方式給你的源代碼添加額外的數(shù)據(jù)。這樣,Swagger 就可以檢測(cè)到這些數(shù)據(jù),自動(dòng)生成對(duì)應(yīng)的 API 文檔。
規(guī)范
Swagger Specification(Swagger 規(guī)范),規(guī)定了如何對(duì) API 的信息進(jìn)行正確描述。
Swagger 規(guī)范,以前稱作 Swagger Specification,現(xiàn)在稱作 OpenAPI Specification(簡(jiǎn)稱 OAS)。
Swagger 規(guī)范本身是與編程語(yǔ)言無(wú)關(guān)的,它支持兩種語(yǔ)法風(fēng)格:
- YAML 語(yǔ)法
- JSON 語(yǔ)法
這兩種語(yǔ)法風(fēng)格可以相互轉(zhuǎn)換,都可以用來(lái)對(duì)我們的 RESTful API 接口的信息進(jìn)行準(zhǔn)確描述,便于人類和機(jī)器閱讀。
在 Swagger 中,用于描述 API 信息的文檔被稱作 Swagger 文檔。Swagger 的規(guī)范主要有兩種:
- Swagger 2.0
- OpenAPI 3.0
關(guān)于 Swagger 規(guī)范的詳細(xì)信息,請(qǐng)參考官方文檔
Swagger文檔
Swagger 文檔(文件),指的是符合 Swagger 規(guī)范的文件,用于對(duì) API 的信息進(jìn)行完整地描述。
Swagger 文檔是整個(gè) Swagger 生態(tài)的核心。
Swagger 文檔的類型有兩種:yaml 文件和 json 文件。
yaml 文件用的是 YAML 語(yǔ)法風(fēng)格;json 文件用的是 JSON 語(yǔ)法風(fēng)格。這兩種文件都可以用來(lái)描述 API 的信息,且可以相互轉(zhuǎn)換。
簡(jiǎn)單的說(shuō),Swagger 文檔就是 API 文檔,只不過(guò) Swagger 文檔是用特定的語(yǔ)法來(lái)編寫的。Swagger 文檔本身看起來(lái)并不美觀,這時(shí),就需要一個(gè)好的 UI 工具將其渲染一番,這個(gè)工具就是 Swagger-ui。
我們可以用任何編輯器來(lái)編寫 Swagger 文檔,但為了方便在編輯的同時(shí),檢測(cè) Swagger 文檔是否符合規(guī)范,就有了 Swagger-editor 編輯器。
Swagger工具
Swagger提供了多種工具,幫助解決api的不同的情況下的問(wèn)題
Swagger-editor
【功能】
- 編寫 Swagger 文檔
- 實(shí)時(shí)檢測(cè) Swagger 文檔是否符合 Swagger 規(guī)范
- 調(diào)試 Swagger 文檔里描述的 API 接口
- 轉(zhuǎn)換 Swagger 文檔(yaml 轉(zhuǎn) json,或 json 轉(zhuǎn) yaml)
【安裝】
- Web 版本的 Swagger-editor 直接運(yùn)行在公網(wǎng)上,Swagger 已經(jīng)給我們配置好了在線的 Swagger-editor。
- 也可以選擇本地運(yùn)行 Swagger-editor,需要 Node.js 環(huán)境支持。
本文使用docker部署,下載swagger-editor的容器
docker pull swaggerapi/swagger-editor
docker run -d -p 81:8080 swaggerapi/swagger-editor
//啟動(dòng),81:8080 將容器的8080端口暴露給localhost的81端口
在瀏覽中輸入:localhost:81,就可以在容器中編輯api文檔
【使用說(shuō)明】:
Swagger-editor 分為菜單欄和主體界面兩個(gè)部分。
主體界面分為左右兩欄,左側(cè)是編輯區(qū),右側(cè)是顯示區(qū)。
- 編輯區(qū)里默認(rèn)有一個(gè) Swagger 文檔的樣例,你可以將其清空,編寫自己的 API 描述。
- 顯示區(qū)是對(duì)應(yīng)編輯區(qū)中的Swagger 文檔的 UI 渲染情況,也就是說(shuō),右側(cè)顯示區(qū)的結(jié)果和使用 Swagger-ui 渲染 Swagger 文檔后的顯示結(jié)果基本一致。
Swagger-editor 的菜單欄包含以下幾個(gè)菜單:
- File: 用于導(dǎo)入、導(dǎo)出、轉(zhuǎn)換、清空 Swagger 文檔
- Edit: 用于轉(zhuǎn)換為標(biāo)準(zhǔn)的 YAML 格式文件,比如刪除空白行等
- Generate Server: 用于構(gòu)建服務(wù)器端 stub
- Generate Client: 用于構(gòu)建客戶端 SDK
選擇菜單欄【File】Save as YAML,保存為swagger.yaml文件,就是我們所說(shuō)的swagger文檔。
文檔編輯參考swagger從入門到精通
Swagger-ui
Swagger-ui 是一套 HTML/CSS/JS 框架,用于渲染 Swagger 文檔,以便提供美觀的 API 文檔界面。也就是說(shuō),Swagger-ui 是一個(gè) UI 渲染工具。
【安裝】
docker部署,下載swagger-ui的容器
docker pull swaggerapi/swagger-ui
【使用】
- 使用上面部署的Swagger-editor,在編輯框中完成文檔編輯后在頁(yè)面上上方點(diǎn)擊 File -> Download JSON,將文件下載到本地(/Users/jiangsuyao/Downloads)命名為swagger.json
- json文件掛在到容器中
//-e:執(zhí)行容器中/foo/swagger.json
//-v:將/Users/fanfan/Downloads中的swagger.json掛在到 /foo中執(zhí)行
docker run -p 82:8080 -e SWAGGER_JSON=/foo/swagger.json -v /Users/jiangsuyao/Downloads:/foo swaggerapi/swagger-ui
瀏覽器輸入:localhost:82,即可看到與Swagger-editor的顯示區(qū)同樣的內(nèi)容
【基于swagger-ui的接口測(cè)試】
1. 選擇接口點(diǎn)擊【try it out】
2. 修改“Example Value Model”里面參數(shù),點(diǎn)擊“Execute”發(fā)送請(qǐng)求
3. 點(diǎn)擊發(fā)送后會(huì)出現(xiàn)下面視圖,不管發(fā)送成功/失敗。你可以通過(guò)下面視圖來(lái)查看請(qǐng)求數(shù)據(jù):
【springboot集成swagger-ui自動(dòng)生成API文檔】
- 添加依賴
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
- 編寫配置文件
在application同級(jí)目錄新建swagger2文件,添加swagger2配置類
package com.abel.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2 {
/**
* 創(chuàng)建API應(yīng)用
* apiInfo() 增加API相關(guān)信息
* 通過(guò)select()函數(shù)返回一個(gè)ApiSelectorBuilder實(shí)例,用來(lái)控制哪些接口暴露給Swagger來(lái)展現(xiàn),
* 本例采用指定掃描的包路徑來(lái)定義指定要建立API的目錄。
*
* @return
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.abel.example.controller"))
.paths(PathSelectors.any())
.build();
}
/**
* 創(chuàng)建該API的基本信息(這些基本信息會(huì)展現(xiàn)在文檔頁(yè)面中)
* 訪問(wèn)地址:http://項(xiàng)目實(shí)際地址/swagger-ui.html
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring Boot中使用Swagger2構(gòu)建RESTful APIs")
.description("更多請(qǐng)關(guān)注https://blog.csdn.net/u012373815")
.termsOfServiceUrl("https://blog.csdn.net/u012373815")
.contact("abel")
.version("1.0")
.build();
}
}
- 在controller上添加注解,自動(dòng)生成API
package com.abel.example.controller;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import com.abel.example.bean.User;
import io.swagger.annotations.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.abel.example.service.UserService;
import com.abel.example.util.CommonUtil;
@Controller
@RequestMapping(value = "/users")
@Api(value = "用戶的增刪改查")
public class UserController {
@Autowired
private UserService userService;
/**
* 查詢所有的用戶
* api :localhost:8099/users
* @return
*/
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "獲取用戶列表,目前沒(méi)有分頁(yè)")
public ResponseEntity<Object> findAll() {
return new ResponseEntity<>(userService.listUsers(), HttpStatus.OK);
}
/**
* 通過(guò)id 查找用戶
* api :localhost:8099/users/1
* @param id
* @return
*/
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "通過(guò)id獲取用戶信息", notes="返回用戶信息")
public ResponseEntity<Object> getUserById(@PathVariable Integer id) {
return new ResponseEntity<>(userService.getUserById(Long.valueOf(id)), HttpStatus.OK);
}
/**
* 通過(guò)spring data jpa 調(diào)用方法
* api :localhost:8099/users/byname?username=xxx
* 通過(guò)用戶名查找用戶
* @param request
* @return
*/
@RequestMapping(value = "/byname", method = RequestMethod.GET)
@ResponseBody
@ApiImplicitParam(paramType = "query",name= "username" ,value = "用戶名",dataType = "string")
@ApiOperation(value = "通過(guò)用戶名獲取用戶信息", notes="返回用戶信息")
public ResponseEntity<Object> getUserByUserName(HttpServletRequest request) {
Map<String, Object> map = CommonUtil.getParameterMap(request);
String username = (String) map.get("username");
return new ResponseEntity<>(userService.getUserByUserName(username), HttpStatus.OK);
}
/**
* 通過(guò)spring data jpa 調(diào)用方法
* api :localhost:8099/users/byUserNameContain?username=xxx
* 通過(guò)用戶名模糊查詢
* @param request
* @return
*/
@RequestMapping(value = "/byUserNameContain", method = RequestMethod.GET)
@ResponseBody
@ApiImplicitParam(paramType = "query",name= "username" ,value = "用戶名",dataType = "string")
@ApiOperation(value = "通過(guò)用戶名模糊搜索用戶信息", notes="返回用戶信息")
public ResponseEntity<Object> getUsers(HttpServletRequest request) {
Map<String, Object> map = CommonUtil.getParameterMap(request);
String username = (String) map.get("username");
return new ResponseEntity<>(userService.getByUsernameContaining(username), HttpStatus.OK);
}
/**
* 添加用戶啊
* api :localhost:8099/users
*
* @param user
* @return
*/
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
@ApiModelProperty(value="user",notes = "用戶信息的json串")
@ApiOperation(value = "新增用戶", notes="返回新增的用戶信息")
public ResponseEntity<Object> saveUser(@RequestBody User user) {
return new ResponseEntity<>(userService.saveUser(user), HttpStatus.OK);
}
/**
* 修改用戶信息
* api :localhost:8099/users
* @param user
* @return
*/
@RequestMapping(method = RequestMethod.PUT)
@ResponseBody
@ApiModelProperty(value="user",notes = "修改后用戶信息的json串")
@ApiOperation(value = "新增用戶", notes="返回新增的用戶信息")
public ResponseEntity<Object> updateUser(@RequestBody User user) {
return new ResponseEntity<>(userService.updateUser(user), HttpStatus.OK);
}
/**
* 通過(guò)ID刪除用戶
* api :localhost:8099/users/2
* @param id
* @return
*/
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseBody
@ApiOperation(value = "通過(guò)id刪除用戶信息", notes="返回刪除狀態(tài)1 成功 0 失敗")
public ResponseEntity<Object> deleteUser(@PathVariable Integer id) {
return new ResponseEntity<>(userService.removeUser(id.longValue()), HttpStatus.OK);
}
}
注解說(shuō)明
- @Api:用在類上,說(shuō)明該類的作用。
- @ApiOperation:注解來(lái)給API增加方法說(shuō)明。
- @ApiImplicitParams : 用在方法上包含一組參數(shù)說(shuō)明。
- @ApiImplicitParam:用來(lái)注解來(lái)給方法入?yún)⒃黾诱f(shuō)明。
- @ApiResponses:用于表示一組響應(yīng)
- @ApiResponse:用在@ApiResponses中,一般用于表達(dá)一個(gè)錯(cuò)誤的響應(yīng)信息
- @ApiModel:描述一個(gè)Model的信息(一般用在請(qǐng)求參數(shù)無(wú)法使用@ApiImplicitParam注解進(jìn)行描述的時(shí)候)
- @ApiModelProperty:描述一個(gè)model的屬性
其中
@ApiResponse參數(shù):
- code:數(shù)字,如400
- message:信息,如“參數(shù)填寫錯(cuò)誤”
- response:拋出異常的類
@ApiImplicitParam參數(shù): - paramTpye:指定參數(shù)放在哪些地方(header/query/path/body/form)
- name:參數(shù)名
- dataTpye:參數(shù)類型
- required:是否必輸(true/false)
- value:說(shuō)明參數(shù)的意思
- defaultValue:參數(shù)默認(rèn)值
- 下載Swagger UI組件
去官網(wǎng)下載Zip包,或者在github上下載也可以,需要將dist文件夾下的所有文件的復(fù)制到webapp目錄下
原理就是在系統(tǒng)加載的時(shí)候,Swagger配置類去掃描所有添加注釋的接口,并且儲(chǔ)存起來(lái)通過(guò)下面地址進(jìn)行訪問(wèn),返回JSON數(shù)據(jù),在前端界面顯示出來(lái)。
啟動(dòng)項(xiàng)目后,訪問(wèn)http://localhost:8099/swagger-ui.html,顯示如下:
Swagger-Codegen
Swagger Codegen是一個(gè)開源的代碼生成器,根據(jù)Swagger定義的RESTful API可以自動(dòng)建立服務(wù)端和客戶端的連接。Swagger Codegen的源碼可以在Github上找到。
GitHub:https://github.com/swagger-api/swagger-codegen
【安裝】
首先機(jī)器上需要有jdk,然后只要下載一個(gè)cli的文件就可以了
//下載
# wget https://oss.sonatype.org/content/repositories/releases/io/swagger/swagger-codegen-cli/2.2.1/swagger-codegen-cli-2.2.1.jar
//下載之后運(yùn)行,返回結(jié)果可查看其支持的語(yǔ)言
# java -jar swagger-codegen-cli-2.2.1.jar
Available languages: [android, aspnet5, async-scala, cwiki, csharp, cpprest, dart, flash, python-flask, go, groovy, java, jaxrs, jaxrs-cxf, jaxrs-resteasy, jaxrs-spec, inflector, javascript, javascript-closure-angular, jmeter, nancyfx, nodejs-server, objc, perl, php, python, qt5cpp, ruby, scala, scalatra, silex-PHP, sinatra, rails5, slim, spring, dynamic-html, html, html2, swagger, swagger-yaml, swift, tizen, typescript-angular2, typescript-angular, typescript-node, typescript-fetch, akka-scala, CsharpDotNet2, clojure, haskell, lumen, go-server]
//查看支持某個(gè)語(yǔ)言的具體使用幫助,比如java
# java -jar swagger-codegen-cli-2.2.1.jar config-help -l java
【使用】
利用swagger-codegen根據(jù)服務(wù)生成客戶端代碼
//http://petstore.swagger.io/v2/swagger.json是官方的一個(gè)例子,我們可以改成自己的服務(wù)
# java -jar swagger-codegen-cli-2.2.1.jar generate -i http://petstore.swagger.io/v2/swagger.json -l java -o samples/client/pestore/java
在上面這段代碼里,使用了三個(gè)參數(shù),分別是-i和-l和-o。
-i,指定swagger描述文件的路徑,url地址或路徑文件;該參數(shù)為必須
-l,指定生成客戶端代碼的語(yǔ)言,該參數(shù)為必須
-o,指定生成文件的位置(默認(rèn)當(dāng)前目錄)
除了可以指定上面三個(gè)參數(shù),還有一些常用的:
-c ,json格式的配置文件的路徑;文件為json格式,支持的配置項(xiàng)因語(yǔ)言的不同而不同
-a, 當(dāng)獲取遠(yuǎn)程swagger定義時(shí),添加授權(quán)頭信息;URL-encoded格式化的name,逗號(hào)隔開的多個(gè)值
--api-package, 指定生成的api類的包名
--artifact-id ,指定pom.xml的artifactId的值
--artifact-version ,指定pom.xml的artifact的版本
--group-id, 指定pom.xml的groupId的值
--model-package, 指定生成的model類的包名
-s ,指定該參數(shù)表示不覆蓋已經(jīng)存在的文件
-
-t ,指定模版文件所在目錄
生成好的客戶端代碼:
在這里插入圖片描述
參考文檔:
https://blog.csdn.net/u012373815/article/details/82685962
https://www.cnblogs.com/shamo89/p/7680771.html