# Swagger

前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力，经常来不及更新。接口文档对于程序员来说，就跟注释一样，经常会抱怨别人写的代码没有写注释，然而自己写起代码起来，最讨厌的，也是写注释。所以仅仅只通过强制来规范大家是不够的，随着时间推移，版本迭代，接口文档往往很容易就跟不上代码了。

Swagger 是一个规范和完整的框架，用于生成、描述、调用和可视化的 Web 服务。其主要作用如下：

* 接口文档在线自动生成。不需要单独写接口文档，但必须为程序写上对应的注解（程序员真正头疼的不是写不清楚接口的说明，而是文档的格式与组织）；
* 功能测试。可以直接在页面中调用接口，不需要再单独安装 postman 等测试工具；

## 集成 Swagger
在项目的 build.gradle 文件中。在“dependencies”节点增加 Swagger 依赖；

```groovy
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // RESTful API 文档生成工具
    // https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui
    compile group: "io.springfox", name: "springfox-swagger-ui", version: SWAGGER_VERSION
    compile group: "io.springfox", name: "springfox-swagger2", version: SWAGGER_VERSION
```

## 创建 Swagger 配置类
一般情况下将 Swagger 的配置类与SpringBoot 的应用类放在同一个package ，比如“cn.sagacloud.server.datacenter”。
创建 Swagger 配置文件 Swagger2Config.kt文件。

```kotlin
/*
 * ********************************************************************************************************************
 *
 *                     :*$@@%$*:                         ;:                ;;    ;;
 *                   :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
 *                  :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
 *                  =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
 *                  =@*                                  %!              @ $= % %@=   =%@!      %=
 *             *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
 *           %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
 *         ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
 *         $@*   ;@@@%=!:                *@*
 *         =@$    ;;;!=%@@@@=!           =@!
 *          %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
 *           ;%@@$=$@@%*       *@@@$=%@@%;
 *              ::;::             ::;::                                              All rights reserved.
 *
 * ********************************************************************************************************************
 */

package cn.sagacloud.server.datacenter

import org.slf4j.LoggerFactory
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import springfox.documentation.builders.ApiInfoBuilder
import springfox.documentation.builders.ParameterBuilder
import springfox.documentation.builders.PathSelectors
import springfox.documentation.builders.RequestHandlerSelectors
import springfox.documentation.schema.ModelRef
import springfox.documentation.service.ApiInfo
import springfox.documentation.service.Contact
import springfox.documentation.service.Parameter
import springfox.documentation.spi.DocumentationType
import springfox.documentation.spring.web.plugins.Docket
import springfox.documentation.swagger2.annotations.EnableSwagger2

/**
 * RESTful API文档生成器Swagger2配置
 *
 * @author  PLX
 */
@Configuration
@EnableSwagger2
open class Swagger2Config {
    companion object {
        // 日志
        private val logger = LoggerFactory.getLogger(Swagger2Config::class.java)
    } // Companion object

    /**
     * 创建RestApi文档生成器
     *
     * @return  返回文档生成器对象
     */
    @Bean
    open fun createRestApi(): Docket {
        logger.debug("createRestApi")
        val builder = ParameterBuilder()
        val builderComming = ParameterBuilder()
        val builderPhone = ParameterBuilder()
        val pars = ArrayList<Parameter>()
        builder.name("ProjectId").description("项目ID").modelRef(ModelRef("string")).parameterType("header").required(false).build()
        builderComming.name("Coming").description("来源").modelRef(ModelRef("string")).parameterType("header").required(false).build()
        builderPhone.name("Account").description("账号信息").modelRef(ModelRef("string")).parameterType("header").required(false).build()
        pars.add(builder.build())
        pars.add(builderComming.build())
        pars.add(builderPhone.build())
        return Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("cn.sagacloud.server"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(pars)
    } // Function createRestApi()

    /**
     * 返回API信息基本
     *
     * @return  返回Api基本信息
     */
    private fun apiInfo(): ApiInfo {
        return ApiInfoBuilder()
                .title("数据中心API")
                .description("接口中Comming来源信息：扫楼：App-scanBuildingApp、慧运营运维平台：adm、Revit算法：RevitAlgorithm")
                .termsOfServiceUrl("http://www.sagacloud.cn/")
                .contact(Contact("张维新", "", "zhangweixin@sagacloud.cn"))
                .version("2.0")
                .build()
    } // Function apiInfo()
} // Class Swagger2Config
```

* 注解 @Configuration 表明该类是一个配置文件。
* 注解 @EnableSwagger2 表明在该类中定义 Swagger 配置。
