swagger

unique_perfect發表於2020-12-25

Swagger 引言

相信無論是前端還是後端開發,都或多或少地被介面文件折磨過。前端經常抱怨後端給的介面文件和實際情況不一致。後端又覺得編寫及維護介面文件會耗費不少精力,經常來不及更新。其實無論是前端呼叫後端,還是後端呼叫前端,都期望有一個好的介面文件。`但是這個介面文件對於程式設計師來說,就跟註釋一樣,經常還會抱怨別人寫的程式碼沒有寫註釋,然而自己寫起程式碼來,最討厭的也是寫註釋。所以僅僅只聽過強制了來規範大家是不夠的,隨著時間推移,版本迭代,介面文件往往很容易就跟不上程式碼了。

1. 什麼是 Swagger

發現了痛點就要去找解決方案。解決方案用的人多了,就成了標準的規範,這就是 Swagger 的由來。通過這套規範,你只需要按照它的規範去定義介面及介面相關資訊。再通過 Swagger 衍生出來的一系列專案和工具,就可以做到生成各種格式的介面文件,生成多做語言的客戶端和服務端的程式碼,以及線上介面除錯頁面等等。這樣,如果按照新的開發木事,在開發新版本或者迭代版本的時候,只需要更新 Swagger 描述檔案,就可以自動生成介面文件和客戶端程式碼,做到呼叫端程式碼、服務端程式碼以及介面文件的一致性。
但即便如此,對於許多開發來說,編寫這個 yml 或 json 格式的描述檔案,本身也是有一定負擔的工作,特別是在後面持續迭代開發的時候,往往會忽略更新這個描述檔案,直接更改程式碼。久而久之,這個描述檔案也和實際專案漸行漸遠,基於該描述檔案生成的介面文件也失去了參考意義。**所以作為 Java 界服務端的大一統框架 Spring,迅速將 Swagger 規範納入自身的標準,建立了 Spring-swagger 專案,後面改成了現在的 Springfox。通過在專案中引入 Springfox,可以掃描相關的程式碼,生成該描述檔案,進而生成與程式碼一致的介面文件和客戶端程式碼。**這種通過程式碼生成介面文件的形式,在後面需求持續迭代的專案中,顯得尤為重要和高效。

在這裡插入圖片描述

 總結:Swagger 就是一個用來定義介面標準,介面規範,同時能根據你的程式碼自動生成介面說明文件的一個工具。

2. 官方提供的工具

在這裡插入圖片描述

Swagger Codegen:通過Codegen 可以將描述檔案生成 html 格式和 cwiki 形式的介面文件,同時也能生成多種語言的服務端和客戶端程式碼。支援通過 jar 包、docker、node 等方式在本地化執行生成。也可以在後面的 Swagger Editor 中線上生成。

Swagger UI:提供了一個視覺化的 UI 頁面展示描述檔案。介面的呼叫方、測試、專案經理等都可以在該頁面中對相關介面進行查閱和做一些簡單的介面請求。該專案支援線上匯入描述檔案和本地部署 UI 專案。

Swagger Editor:類似於 Markdown 編輯器的編輯 Swagger 描述檔案的編輯器,該編輯器支援實時預覽描述檔案的更新效果,也提供了線上編輯器和本地部署器倆種方式。

​		Swagger Inspector:感覺和 Postman 差不多,是一個可以對介面進行測試的線上版的 postman。比如在 Swagger UI 裡面做介面請求,會返回更多的資訊,也會儲存你請求的實際請求引數等資料。

​		Swagger Hub:整合了上面所有專案的各個功能,你可以以專案和版本為單位,將你的描述檔案上傳到 Swagger Hub 中。在 Swagger Hub 中可以完成上面專案的所有工作,需要註冊賬號,分免費版和收費版。

​		Springfox Swagger:Spring 基於 Swagger 規範,可以將基於 SpringMVC 和 Spring Boot 專案的專案程式碼,自動生成 JSON 格式的描述檔案。本身不是屬於 Swagger 官網提供的,在這裡列出來做個說明,方便後面作一個使用的展開。

3. 構建 Swagger 與 Spring Boot 環境

3.1 引入依賴

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

3.2 編寫 Swagger 配置類

這個配置類基本都是不變的。
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.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2  
public class SwaggerConfig {

    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .pathMapping("/")
                .select()
                // 掃描哪個介面的包
                .apis(RequestHandlerSelectors.basePackage("com.baiyi.controller"))
                .paths(PathSelectors.any())
                .build().apiInfo(new ApiInfoBuilder()
                        .title("標題: SpringBoot 整合 Swagger 使用")
                        .description("詳細資訊: SpringBoot 整合 Swagger,詳細資訊......")
                        // 版本資訊
                        .version("1.1")
                        // 開發文件的聯絡人
                        .contact(new Contact("baiyi", "http://www.baidu.com","1101293873@qq.com"))
                        .license("This Baidu License")
                        .licenseUrl("http://www.baidu.com")
                        .build());
    }
}

3.3 啟動 SpringBoot 專案

在這裡插入圖片描述

3.4 訪問 Swagger 的 UI 介面

訪問 Swagger 提供的 UI 介面:http://localhost:8080/swagger-ui.html

在這裡插入圖片描述

4. 使用 Swagger 構建

4.1 開發 Controller 介面

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class HelloController {

    @GetMapping("/findAll")
    public Map<String,Object> findAll(){
        Map<String, Object> map = new HashMap<>();
        map.put("success", "查詢所有資料成功");
        map.put("status", true);
        return map;
    }
}

4.2 重啟專案訪問介面介面

在這裡插入圖片描述

5. Swagger 註解

5.1 @Api

作用:用來指定介面的描述文字
修飾範圍:用在類上
@RequestMapping("/user")
@Api(tags = "使用者服務相關介面描敘")
public class HelloController {

		....
}

5.2 @ApiOperation

作用:用來對介面中具體方法做描敘
修飾範圍:用在方法上
@GetMapping("/findAll")
@ApiOperation(value = "查詢所有使用者介面",
        notes = "<span style='color:red;'>描敘:</span>&nbsp;&nbsp;用來查詢所有使用者資訊的介面")
public Map<String,Object> findAll(){
    Map<String, Object> map = new HashMap<>();
    map.put("success", "查詢所有資料成功");
    map.put("status", true);
    return map;
}

5.3 @ApiImplicitParams

作用:用來介面中引數進行說明
修飾範圍:用在方法上

5.3.1 普通引數使用

@PostMapping("save")
@ApiOperation(value = "儲存使用者資訊介面",
        notes = "<span style='color:red;'>描敘:</span>&nbsp;&nbsp;用來儲存使用者資訊的介面")
@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "使用者 id", dataType = "String", defaultValue = "21"),
        @ApiImplicitParam(name = "name", value = "使用者姓名", dataType = "String", defaultValue = "白衣")
})
public Map<String, Object> save(String id, String name) {
    System.out.println("id = " + id);
    System.out.println("name = " + name);
    Map<String, Object> map = new HashMap<>();
    map.put("id", id);
    map.put("name", name);
    return map;
}

在這裡插入圖片描述

5.3.2 RestFul 風格使用

如果使用的是 RestFul 風格進行傳參,必須再新增一個 paramType="path"
@PostMapping("save/{id}/{name}")
@ApiOperation(value = "儲存使用者資訊介面",
        notes = "<span style='color:red;'>描敘:</span>&nbsp;&nbsp;用來儲存使用者資訊的介面")
@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "使用者 id", dataType = "String", defaultValue = "21", paramType = "path"),
        @ApiImplicitParam(name = "name", value = "使用者姓名", dataType = "String", defaultValue = "白衣", paramType = "path")
})
public Map<String, Object> save(@PathVariable("id") String id,@PathVariable("name") String name) {
    System.out.println("id = " + id);
    System.out.println("name = " + name);
    Map<String, Object> map = new HashMap<>();
    map.put("id", id);
    map.put("name", name);
    return map;
}

在這裡插入圖片描述

5.3.3 JSON 格式使用

如果是 RequestBody 的方式,需要定義一個物件進行接收。
1. 定義一個 User 物件
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String id;
    private String name;
}
2. 編寫 Controller
@PostMapping("save2")
public Map<String, Object> save2(@RequestBody User user) {
    System.out.println("id = " + user.getId());
    System.out.println("name = " + user.getName());
    Map<String, Object> map = new HashMap<>();
    map.put("id", user.getId());
    map.put("name", user.getName());
    return map;
}
3. 重啟專案,開啟 UI 介面

在這裡插入圖片描述

測試:
在這裡插入圖片描述

5.4 @ApiResponses

作用:用在請求的方法上,表示一組響應
修飾範圍:用在方法上
@PostMapping("save2")
@ApiResponses({
        @ApiResponse(code = 404, message = "請求路徑不對"),
        @ApiResponse(code = 400, message = "程式不對")
})
public Map<String, Object> save2(@RequestBody User user) {
    System.out.println("id = " + user.getId());
    System.out.println("name = " + user.getName());
    Map<String, Object> map = new HashMap<>();
    map.put("id", user.getId());
    map.put("name", user.getName());
    return map;
}

在這裡插入圖片描述

相關文章