什么是swagger,一篇帶你入門


一、前言

在前后端分離開發的過程中,前端和后端需要進行api對接進行交互,就需要一個api規范文檔,方便前后端的交互,但api文檔不能根據代碼的變化發生實時動態的改變,這樣后端修改了接口,前端不能及時獲取最新的接口,導致調用出錯,需要手動維護api文檔,加大了開發的工作量和困難,而swagger的出現就是為了解決這一系列的問題。

二、swagger的概述

swagger是一套基於OpenAPI規范構建的開源工具,使用RestApi
1、代碼變,文檔變
2、跨語言,支持多種語言
3、swagger-ui 呈現出來的是一份可交互式的API文檔,可以直接在文檔頁面嘗試API的調用
4、可以將文檔規范導入相關工具(postman、soapui),這些工具將會為我們自動地創建自動化測試

補充:

RestApi格式是根據請求的方式決定本次請求的一個操作,譬如:get-->讀,post-->寫(增、刪、改),put-->修改,delete-->刪除
OpenApi與語言無關,只是一種規范,可以使用yaml和json格式進行編寫,這樣更利於我們和機器進行閱讀

swagger主要包含了以下三個部分:

  • swagger editor:基於瀏覽器的編輯器,我們可以使用它編寫我們OpenApi規范(yaml或者json配置)
  • Swagger UI:他會將我們編寫的OpenApi規范呈現為交互式的API文檔,后文我將使用瀏覽器來查看並且操作我們的RestApi
  • Swagger Codegen:它可以通過OpenApi規范定義的任何API生成服務器存根和客戶端SDK來簡化構建過程

使用swagger就是把相關信息存儲在它定義的描述文件里面(yml或json格式),再通過維護這個描述文件可以去更新接口文檔,以及生成各端代碼

三、springfox概述

使用swagger時如果碰見版本更新迭代時,只需要更改swagger的描述文件即可,但是在頻繁的更新項目版本時很多開發人員認為即使修改描述文件(yml或json文件)也是一定的工作負擔,久而久之就直接修改代碼,而不去修改描述文件了,這樣基於描述文件生成接口文檔也失去了意義。
Marty Pitt編寫了一個基於spring的組件swagger-springmvc,Spring-fox就是根據這個組件發展而來的全新項目;
Spring-fox是根據代碼生成接口文檔,所以正常的進行更新項目版本,修改代碼即可,而不需要跟隨修改描述文件(yml或json文件);
spring-fox利用自身AOP特性,把swagger集成進來,底層還是Swagger,但是使用起來卻方便很多,所以在實際開發中,都是直接使用spring-fox。

四、swagger的使用

1、新建springboot項目
2、導入相關依賴

<!-- 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、啟動類中添加@EnableSwagger2注解
@enableSwagger2:是springfox提供的一個注解,代表swagger2相關技術開啟,會掃描當前類所在包,以及子包中所有的類型中的注解,做swagger文檔的定值
4、編寫一個簡單api接口

@RestController
public class HelloController {
    
    @GetMapping("/get")
    public String get() {
        return "get";
    }
    
    @PostMapping("/post")
    public String post() {
        return "post";
    }
    
    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }
}

5、啟動項目,並在瀏覽器輸入http://localhost:8080/swagger-ui.html進行swagger-ui界面訪問

4.1 swagger的基礎信息配置-->config類

@Configuration
@EnableSwagger2 //開啟swagger2,若啟動類上添加了該注解,則配置類可以不添加
public class SwaggerConfig {

    // 創建swagger bean
    @Bean
    public Docket docket() {
        // Docket是swagger全局配置對象
        // DocumentationType:指定文檔類型為swagger2
        return new Docket(DocumentationType.SWAGGER_2)
                // swagger信息
                .apiInfo(apiInfo());
    }

    // swagger文檔信息
    public ApiInfo apiInfo() {
        // 作者信息
        Contact contact = new Contact(
                // 文檔發布者的名稱
                "iqiuq",
                // 文檔發布者的網站地址
                "https://iqiuq.gitee.io/qiuqblogs/",
                // 文檔發布者的電子郵箱
                "qiuyonghui258@163.com"
        );
        return new ApiInfo(
                // 標題
                "iqiuq swagger api",
                // 文檔描述
                "演好自己人生的劇本",
                // 版本號
                "1.0",
                // 服務組url地址
                "urn:tos", 
                // 作者信息
                contact,
                // 開源組織
                "Apache 2.0",
                // 開源地址
                "http://www.apache.org/licenses/LICENSE-2.0",
                // 集合
                new ArrayList()
        );
    }
}

4.2 swagger掃描包配置

@Configuration
@EnableSwagger2 //開啟swagger2
public class SwaggerConfig {

    // 創建swagger bean
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                // swagger信息
                .apiInfo(apiInfo())
                // swagger 掃描包配置
                // select()獲取Docket中的選擇器,返回ApiSelectorBuilder構造選擇器,如掃描掃描包的注解
                .select()
                /**
                 * requestHandlerSelectors:請求處理選擇器
                 * basePackage():掃描指定包下的所有接口
                 * any():掃描所有的包
                 * none():不掃描
                 * withClassAnnotation():掃描指定類上的注解,參數是一個注解的放射對象
                 * withMethodAnnotation():掃描方法上的注解
                 */
                // 指定掃描器掃描的規則(斷言)
                .apis(RequestHandlerSelectors.basePackage("com.iqiuq.swaggerdemo.controller"))
                /**
                 * pathSelectors:路徑選擇器,過濾路徑
                 * ang():選擇所有路徑
                 * none():都不選擇
                 * ant():選擇指定路徑
                 * regex():正則表達式
                 */
                .paths(PathSelectors.regex("/hello"))
                .build();
    }
        return new ApiInfo(
                // 標題
                "iqiuq swagger api",
                // 文檔描述
                "演好自己人生的劇本",
                // 版本號
                "1.0",
                // 服務組url地址
                "urn:tos", 
                // 作者信息
                contact,
                // 開源組織
                "Apache 2.0",
                // 開源地址
                "http://www.apache.org/licenses/LICENSE-2.0",
                // 集合
                new ArrayList()
        );
}

4.3 配置是否開啟swagger

@Configuration
@EnableSwagger2 //開啟swagger2
public class SwaggerConfig {

    // 創建swagger bean
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                // swagger信息
                .apiInfo(apiInfo())
                // 配置是否開啟swagger,若為false,則瀏覽器不能訪問
                .enable(false);
    }

    // swagger文檔信息
    public ApiInfo apiInfo() {
        // 作者信息
        Contact contact = new Contact(
                "iqiuq",
                "https://iqiuq.gitee.io/qiuqblogs/",
                "qiuyonghui258@163.com");
        return new ApiInfo(
                "iqiuq swagger api",
                "演好自己人生的劇本",
                "1.0",
                "urn:tos", contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList());
    }
}

需求:開發和測試環境中開啟swagger,其他環境不開啟

@Configuration
@EnableSwagger2 //開啟swagger2
public class SwaggerConfig {

    // 創建swagger bean
    @Bean
    public Docket docket(Environment environment) {
        // 配置swagger的docket的bean實例
        Profiles profiles = Profiles.of("dev","test");
        // 通過environment.acceptsProfiles()判斷是否指定的環境中,是,則為true
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(flag)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.iqiuq.swaggerdemo.controller"))
                .paths(PathSelectors.regex("/hello"))
                .build();
    }

    // swagger文檔信息
    public ApiInfo apiInfo() {
        Contact contact = new Contact(
                "iqiuq",
                "https://iqiuq.gitee.io/qiuqblogs/",
                "qiuyonghui258@163.com");
        return new ApiInfo(
                "iqiuq swagger api",
                "演好自己人生的劇本",
                "1.0",
                "urn:tos", 
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList());
    }
}

4.3 swagger分組配置

每個組就是一個docket實例,多個組就是創建多個docket的實例

@Configuration
@EnableSwagger2 //開啟swagger2
public class SwaggerConfig {

    // 創建swagger bean
    @Bean
    public Docket docket1(Environment environment) {
        // 配置swagger的docket的bean實例
        Profiles profiles = Profiles.of("dev","test");
        // 通過environment.acceptsProfiles()判斷是否指定的環境中,是,則為true
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                // swagger信息
                .apiInfo(apiInfo())
                // 配置是否開啟swagger,若為false,則瀏覽器不能訪問
                .enable(flag)
                // 配置組名
                .groupName("iqiuq")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.iqiuq.swaggerdemo.controller"))
                .paths(PathSelectors.regex("/hello"))
                .build();
    }

    @Bean
    public Docket docket2(Environment environment) {
        Profiles profiles = Profiles.of("dev","test");
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(flag)
                .groupName("哈哈哈")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.iqiuq.swaggerdemo.controller"))
                .paths(PathSelectors.regex("/hello"))
                .build();
    }

    @Bean
    public Docket docket3(Environment environment) {
        Profiles profiles = Profiles.of("dev","test");
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(flag)
                .groupName("嘻嘻嘻")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.iqiuq.swaggerdemo.controller"))
                .paths(PathSelectors.regex("/hello"))
                .build();
    }
    // swagger文檔信息
    public ApiInfo apiInfo() {
        Contact contact = new Contact(
                "iqiuq",
                "https://iqiuq.gitee.io/qiuqblogs/",
                "qiuyonghui258@163.com");
        return new ApiInfo(
                "iqiuq swagger api",
                "演好自己人生的劇本",
                "1.0",
                "urn:tos", 
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList());
    }

注意:

如果你使用的是swagger 3.0 你就需要使用
 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>3.0.0</version>
</dependency>

訪問:http://localhost:8080/swagger-ui/index.html  就可以實現swagger-ui.html的訪問

五、swagger常用注解

swagger注解主要是用來給swagger生成的接口文檔說明用的

5.1 @Api

  • @Api:是類上注解,控制整個類生成接口信息的內容
    • tags:類的名稱,可以有多個值,多個值表示多個副本,在UI視圖中就顯示幾個控制器訪問菜單
    • description:描述,已過時

5.2 @ApiOperation

  • @ApiOperation:方法的說明,value值必須提供
    • value:說明方法的作用
    • notes:方法的備注說明

5.3 @ApiParam

  • @ApiParam:可以作用於方法參數和成員變量
    • name:參數別名
    • value:參數的描述
    • required:是否必須需要

5.4 @ApiIgnore

  • @Apilgnore:忽略,當前注解描述的方法或類型,不生成api文檔

5.5 @ApiImplicitParam和@ApiImplicitParams

  • @ApiImplicitParam:使用在方法上,描述方法的單個參數
    • name:參數名稱
    • value:描述
    • required:是否必要參數
    • paramType:參數類型
    • dataType:數據類型
  • @ApiImplicitParams:使用在方法上,描述方法的一組參數
    • value:是@ApiImplicitParam類型的數組

5.6 @ApiModel和@ApiModelProperty

  • @ApiModel:描述一個實體類型,這個實體類型如果成為任何一個生成api幫助文檔方法的一個返回值類型的時候,此注解被解析
    • value:自定義實體
    • description:詳細描述
  • @ApiModelProperty:實體類屬性描述
    • name:字段別名
    • value:字段描述
    • required:是否是必須字段
    • example:示例數據
    • hidden:是否隱藏數據

5.7 @ApiResponse和@ApiResponses

@ApiResponses、@ApiResponse方法返回值的說明

  • @ApiResponses:方法返回對象的說明
  • @ApiResponse:每個參數的說明
    • code:數字,例如:300
    • message:信息,例如:”請求參數沒填好"
    • response:拋出異常的類

5.8 其他注解

  • @Authorization:聲明要在資源或操作上使用的授權方案
  • @AuthorizationScope:描述OAuth2授權范圍
  • @ResponseHeader:表示可以作為響應的一部分提供的標頭
  • @ApiProperty:描述POJO對象中的屬性值
  • @ApiError:接口錯誤所返回的信息

六、總結

  1. 我們可以通過swagger給一些比較難理解的屬性或接口,增加注釋信息
  2. 接口文檔實時更新
  3. 可以在線測試
  4. 在正式發布的時候,關閉swagger,出於安全考慮,而且節省內存


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM