簡介
Swagger 是最流行的 API 開發工具,它遵循 OpenAPI Specification(OpenAPI 規范,也簡稱 OAS)。
Swagger 可以貫穿于整個 API 生態,如 API 的設計、編寫 API 文檔、測試和部署。
Swagger 是一種通用的,和編程語言無關的 API 描述規范。
應用場景
- 如果你的 RESTful API 接口都開發完成了,你可以用 Swagger-editor 來編寫 API 文檔( yaml 文件 或 json 文件),然后通過 Swagger-ui 來渲染該文件,以非常美觀的形式將你的 API 文檔,展現給你的團隊或者客戶。
- 如果你的 RESTful API 還未開始,也可以使用 Swagger ,來設計和規范你的 API,以 Annotation (注解)的方式給你的源代碼添加額外的數據。這樣,Swagger 就可以檢測到這些數據,自動生成對應的 API 文檔。
規范
Swagger Specification(Swagger 規范),規定了如何對 API 的信息進行正確描述。
Swagger 規范,以前稱作 Swagger Specification,現在稱作 OpenAPI Specification(簡稱 OAS)。
Swagger 規范本身是與編程語言無關的,它支持兩種語法風格:
- YAML 語法
- JSON 語法
這兩種語法風格可以相互轉換,都可以用來對我們的 RESTful API 接口的信息進行準確描述,便于人類和機器閱讀。
在 Swagger 中,用于描述 API 信息的文檔被稱作 Swagger 文檔。Swagger 的規范主要有兩種:
- Swagger 2.0
- OpenAPI 3.0
關于 Swagger 規范的詳細信息,請參考官方文檔
Swagger文檔
Swagger 文檔(文件),指的是符合 Swagger 規范的文件,用于對 API 的信息進行完整地描述。
Swagger 文檔是整個 Swagger 生態的核心。
Swagger 文檔的類型有兩種:yaml 文件和 json 文件。
yaml 文件用的是 YAML 語法風格;json 文件用的是 JSON 語法風格。這兩種文件都可以用來描述 API 的信息,且可以相互轉換。
簡單的說,Swagger 文檔就是 API 文檔,只不過 Swagger 文檔是用特定的語法來編寫的。Swagger 文檔本身看起來并不美觀,這時,就需要一個好的 UI 工具將其渲染一番,這個工具就是 Swagger-ui。
我們可以用任何編輯器來編寫 Swagger 文檔,但為了方便在編輯的同時,檢測 Swagger 文檔是否符合規范,就有了 Swagger-editor 編輯器。
Swagger工具
Swagger提供了多種工具,幫助解決api的不同的情況下的問題
Swagger-editor
【功能】
- 編寫 Swagger 文檔
- 實時檢測 Swagger 文檔是否符合 Swagger 規范
- 調試 Swagger 文檔里描述的 API 接口
- 轉換 Swagger 文檔(yaml 轉 json,或 json 轉 yaml)
【安裝】
- Web 版本的 Swagger-editor 直接運行在公網上,Swagger 已經給我們配置好了在線的 Swagger-editor。
- 也可以選擇本地運行 Swagger-editor,需要 Node.js 環境支持。
本文使用docker部署,下載swagger-editor的容器
docker pull swaggerapi/swagger-editor
docker run -d -p 81:8080 swaggerapi/swagger-editor
//啟動,81:8080 將容器的8080端口暴露給localhost的81端口
在瀏覽中輸入:localhost:81,就可以在容器中編輯api文檔
【使用說明】:
Swagger-editor 分為菜單欄和主體界面兩個部分。
主體界面分為左右兩欄,左側是編輯區,右側是顯示區。
- 編輯區里默認有一個 Swagger 文檔的樣例,你可以將其清空,編寫自己的 API 描述。
- 顯示區是對應編輯區中的Swagger 文檔的 UI 渲染情況,也就是說,右側顯示區的結果和使用 Swagger-ui 渲染 Swagger 文檔后的顯示結果基本一致。
Swagger-editor 的菜單欄包含以下幾個菜單:
- File: 用于導入、導出、轉換、清空 Swagger 文檔
- Edit: 用于轉換為標準的 YAML 格式文件,比如刪除空白行等
- Generate Server: 用于構建服務器端 stub
- Generate Client: 用于構建客戶端 SDK
選擇菜單欄【File】Save as YAML,保存為swagger.yaml文件,就是我們所說的swagger文檔。
文檔編輯參考swagger從入門到精通
Swagger-ui
Swagger-ui 是一套 HTML/CSS/JS 框架,用于渲染 Swagger 文檔,以便提供美觀的 API 文檔界面。也就是說,Swagger-ui 是一個 UI 渲染工具。
【安裝】
docker部署,下載swagger-ui的容器
docker pull swaggerapi/swagger-ui
【使用】
- 使用上面部署的Swagger-editor,在編輯框中完成文檔編輯后在頁面上上方點擊 File -> Download JSON,將文件下載到本地(/Users/jiangsuyao/Downloads)命名為swagger.json
- json文件掛在到容器中
//-e:執行容器中/foo/swagger.json
//-v:將/Users/fanfan/Downloads中的swagger.json掛在到 /foo中執行
docker run -p 82:8080 -e SWAGGER_JSON=/foo/swagger.json -v /Users/jiangsuyao/Downloads:/foo swaggerapi/swagger-ui
瀏覽器輸入:localhost:82,即可看到與Swagger-editor的顯示區同樣的內容
【基于swagger-ui的接口測試】
1. 選擇接口點擊【try it out】
2. 修改“Example Value Model”里面參數,點擊“Execute”發送請求
3. 點擊發送后會出現下面視圖,不管發送成功/失敗。你可以通過下面視圖來查看請求數據:
【springboot集成swagger-ui自動生成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同級目錄新建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 {
/**
* 創建API應用
* apiInfo() 增加API相關信息
* 通過select()函數返回一個ApiSelectorBuilder實例,用來控制哪些接口暴露給Swagger來展現,
* 本例采用指定掃描的包路徑來定義指定要建立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();
}
/**
* 創建該API的基本信息(這些基本信息會展現在文檔頁面中)
* 訪問地址:http://項目實際地址/swagger-ui.html
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Spring Boot中使用Swagger2構建RESTful APIs")
.description("更多請關注https://blog.csdn.net/u012373815")
.termsOfServiceUrl("https://blog.csdn.net/u012373815")
.contact("abel")
.version("1.0")
.build();
}
}
- 在controller上添加注解,自動生成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 = "獲取用戶列表,目前沒有分頁")
public ResponseEntity<Object> findAll() {
return new ResponseEntity<>(userService.listUsers(), HttpStatus.OK);
}
/**
* 通過id 查找用戶
* api :localhost:8099/users/1
* @param id
* @return
*/
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "通過id獲取用戶信息", notes="返回用戶信息")
public ResponseEntity<Object> getUserById(@PathVariable Integer id) {
return new ResponseEntity<>(userService.getUserById(Long.valueOf(id)), HttpStatus.OK);
}
/**
* 通過spring data jpa 調用方法
* api :localhost:8099/users/byname?username=xxx
* 通過用戶名查找用戶
* @param request
* @return
*/
@RequestMapping(value = "/byname", method = RequestMethod.GET)
@ResponseBody
@ApiImplicitParam(paramType = "query",name= "username" ,value = "用戶名",dataType = "string")
@ApiOperation(value = "通過用戶名獲取用戶信息", 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);
}
/**
* 通過spring data jpa 調用方法
* api :localhost:8099/users/byUserNameContain?username=xxx
* 通過用戶名模糊查詢
* @param request
* @return
*/
@RequestMapping(value = "/byUserNameContain", method = RequestMethod.GET)
@ResponseBody
@ApiImplicitParam(paramType = "query",name= "username" ,value = "用戶名",dataType = "string")
@ApiOperation(value = "通過用戶名模糊搜索用戶信息", 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);
}
/**
* 通過ID刪除用戶
* api :localhost:8099/users/2
* @param id
* @return
*/
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseBody
@ApiOperation(value = "通過id刪除用戶信息", notes="返回刪除狀態1 成功 0 失敗")
public ResponseEntity<Object> deleteUser(@PathVariable Integer id) {
return new ResponseEntity<>(userService.removeUser(id.longValue()), HttpStatus.OK);
}
}
注解說明
- @Api:用在類上,說明該類的作用。
- @ApiOperation:注解來給API增加方法說明。
- @ApiImplicitParams : 用在方法上包含一組參數說明。
- @ApiImplicitParam:用來注解來給方法入參增加說明。
- @ApiResponses:用于表示一組響應
- @ApiResponse:用在@ApiResponses中,一般用于表達一個錯誤的響應信息
- @ApiModel:描述一個Model的信息(一般用在請求參數無法使用@ApiImplicitParam注解進行描述的時候)
- @ApiModelProperty:描述一個model的屬性
其中
@ApiResponse參數:
- code:數字,如400
- message:信息,如“參數填寫錯誤”
- response:拋出異常的類
@ApiImplicitParam參數: - paramTpye:指定參數放在哪些地方(header/query/path/body/form)
- name:參數名
- dataTpye:參數類型
- required:是否必輸(true/false)
- value:說明參數的意思
- defaultValue:參數默認值
- 下載Swagger UI組件
去官網下載Zip包,或者在github上下載也可以,需要將dist文件夾下的所有文件的復制到webapp目錄下
原理就是在系統加載的時候,Swagger配置類去掃描所有添加注釋的接口,并且儲存起來通過下面地址進行訪問,返回JSON數據,在前端界面顯示出來。
啟動項目后,訪問http://localhost:8099/swagger-ui.html,顯示如下:
Swagger-Codegen
Swagger Codegen是一個開源的代碼生成器,根據Swagger定義的RESTful API可以自動建立服務端和客戶端的連接。Swagger Codegen的源碼可以在Github上找到。
GitHub:https://github.com/swagger-api/swagger-codegen
【安裝】
首先機器上需要有jdk,然后只要下載一個cli的文件就可以了
//下載
# wget https://oss.sonatype.org/content/repositories/releases/io/swagger/swagger-codegen-cli/2.2.1/swagger-codegen-cli-2.2.1.jar
//下載之后運行,返回結果可查看其支持的語言
# 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]
//查看支持某個語言的具體使用幫助,比如java
# java -jar swagger-codegen-cli-2.2.1.jar config-help -l java
【使用】
利用swagger-codegen根據服務生成客戶端代碼
//http://petstore.swagger.io/v2/swagger.json是官方的一個例子,我們可以改成自己的服務
# 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
在上面這段代碼里,使用了三個參數,分別是-i和-l和-o。
-i,指定swagger描述文件的路徑,url地址或路徑文件;該參數為必須
-l,指定生成客戶端代碼的語言,該參數為必須
-o,指定生成文件的位置(默認當前目錄)
除了可以指定上面三個參數,還有一些常用的:
-c ,json格式的配置文件的路徑;文件為json格式,支持的配置項因語言的不同而不同
-a, 當獲取遠程swagger定義時,添加授權頭信息;URL-encoded格式化的name,逗號隔開的多個值
--api-package, 指定生成的api類的包名
--artifact-id ,指定pom.xml的artifactId的值
--artifact-version ,指定pom.xml的artifact的版本
--group-id, 指定pom.xml的groupId的值
--model-package, 指定生成的model類的包名
-s ,指定該參數表示不覆蓋已經存在的文件
-
-t ,指定模版文件所在目錄
生成好的客戶端代碼:
在這里插入圖片描述
參考文檔:
https://blog.csdn.net/u012373815/article/details/82685962
https://www.cnblogs.com/shamo89/p/7680771.html