Swagger詳細了解一下

簡介

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

【使用】

  1. 使用上面部署的Swagger-editor,在編輯框中完成文檔編輯后在頁面上上方點擊 File -> Download JSON,將文件下載到本地(/Users/jiangsuyao/Downloads)命名為swagger.json
  2. 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文檔】

  1. 添加依賴
<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>
  1. 編寫配置文件
    在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();
    }
}
  1. 在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:參數默認值
  1. 下載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

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容