zoukankan      html  css  js  c++  java
  • Swagger 教程

       转自   Vojtech Ruzicka的编程博客

    (一)Swagger和SpringFox

       记录REST API非常重要。它是一个公共接口,其他模块,应用程序或开发人员可以使用它。即使你没有公开曝光它,它仍然很重要。后端和前端代码通常由不同的开发人员处理。创建API的人通常不是消费它的人。因此,拥有适当记录的界面以避免混淆并使其始终保持最新是至关重要的。

    最受欢迎的API文档规范之一是OpenApi,以前称为Swagger。它允许您使用JSON或YAML元数据描述API的属性。它还提供了一个Web UI,它可以将元数据转换为一个很好的HTML文档。此外,通过该UI,您不仅可以浏览有关API端点的信息,还可以将UI用作REST客户端 - 您可以调用任何端点,指定要发送的数据并检查响应。它非常方便。

    然而,手动编写此类文档并在代码更改时保持更新是不现实的。这就是SpringFox发挥作用的地方。它是Spring Framework的Swagger集成。它可以自动检查您的类,检测控制器,它们的方法,它们使用的模型类以及它们映射到的URL。没有任何手写文档,只需检查应用程序中的类,它就可以生成大量有关API的信息。多么酷啊?最重要的是,每当您进行更改时,它们都会反映在文档中。

     

    (二)开始项目

    首先,你需要一个带有一些Rest Controller的Spring Boot应用程序,我在这里准备了一个简单的。

    在本文中,我使用了SpringFox 2.9.2和Spring Boot 1.5.10.RELEASE。它使用Swagger规范的第2版。版本3已经发布,但尚未(截至2014年2月)SpringFox支持。支持应在下一版本中提供

    使用本博文中描述的所有功能构建的最终项目的源代码可在GitHub上获得

     

    (三)添加依赖项

          要在项目中使用SpringFox,您需要先将其添加为依赖项。如果您使用的是Maven,则可以使用以下内容(您可以检查是否有更新的版本)。

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>

    或者如果您使用的是Gradle:

    compile "io.springfox:springfox-swagger2:2.9.2"

     

    (四)基本配置

    添加依赖项后,您需要提供一些基本的Spring配置。虽然您可以在技术上使用现有配置文件之一,但最好为其配置单独的文件。您需要提供的第一件事是@ EnableSwagger2注释。然后你需要提供一个Docket bean,它是用于配置SpringFox的主bean。

    @Configuration
    @EnableSwagger2
    public class SpringFoxConfig {
        @Bean
        public Docket apiDocket() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(PathSelectors.any())
                    .build();
        }
    }

    当然,您可以提供更多配置设置,我们稍后会看到,但这是一个简约配置,它执行以下操作:

    • @ EnableSwagger2支持Swagger 2的SpringFox支持。
    • DocumentationType.SWAGGER_2告诉Docket bean我们正在使用Swagger规范的版本2。
    • select()创建一个构建器,用于定义哪些控制器及其生成的文档中应包含哪些方法。
    • apis()定义要包含的类(控制器和模型类)。这里我们包括所有这些,但您可以通过基础包,类注释等来限制它们。
    • paths()允许您根据路径映射定义应包含哪个控制器的方法。我们现在包括所有这些,但您可以使用正则表达式等限制它。

    (五)添加UI

    如果您现在部署应用程序,则已经生成了描述API的swagger元数据!你可以看看:

    http://localhost:8080/v2/api-docs

    招摇,JSON

    事实证明它只是一个很大的JSON,而不是人类可读的。但你已经可以验证它是否有效。只需转到Swagger在线编辑器并将JSON粘贴到那里。将生成的JSON粘贴到左侧面板,瞧!您现在可以将生成的文档视为HTML页面。不错,不是吗?将这些文档作为应用程序的一部分直接使用会更好。幸运的是,实现这一点非常容易。显示基于JSON输入的HTML文档的GUI称为swagger-ui。要启用它是一个Spring Boot应用程序,您只需要添加此依赖项:

    //MAVEN
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>
    
    //GRADLE 
    compile "io.springfox:springfox-swagger-ui:2.9.2"

    该文档将在此处自动提供:

    http://localhost:8080/swagger-ui.html

     

    招摇的UI

     

    (六)添加ApiInfo

    默认情况下,我们文档的标题部分看起来非常通用:

    招摇头

    现在是时候做点什么了。我们可以通过简单的配置更改来更改那里的所有信息。在SpringFoxConfiguration文件中,我们需要添加ApiInfo对象,该对象提供有关API的一般信息,例如标题,版本,联系人或许可信息。

    @Bean
    public Docket apiDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .apiInfo(getApiInfo());
    }
    
    private ApiInfo getApiInfo() {
        return new ApiInfo(
                "TITLE",
                "DESCIPRION",
                "VERSION",
                "TERMS OF SERVICE URL",
                new Contact("NAME","URL","EMAIL"),
                "LICENSE",
                "LICENSE URL",
                Collections.emptyList()
        );
    }

    现在我们的文档标题应该看起来更好:

    招摇头更新的

    (七)缩小已处理的API

    到现在为止还挺好。但是当你仔细看看生成的文档时,你会发现除了我们使用的模型和控制器类之外,还有一些特定于Spring的类,如Controllers部分中的BasicErrorController以及ViewModelAndView下的型号部分。

    有时,缩小类,SpringFox会将其检测为文档生成源。Controller和Model类。您可以在Docket配置中轻松配置它。还记得像我们使用.apis(RequestHandlerSelectors.any()来包含所有类吗?让我们将它缩小到我们的基础包:

    @Bean
    public Docket apiDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.vojtechruzicka"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(getApiInfo());
    }

    当您想要指定应包含哪些类时,这非常有用。有时您还需要只包含特定的URL路径。您可能正在使用API​​的多个版本以实现向后兼容,但不希望包含历史版本。也许API的某些部分是内部的,不应该是公共文档的一部分。无论哪种方式,也可以在Docket中配置基于URL匹配的这种包含。记住.paths(PathSelectors.any())?您可以将其限制为某些正则表达式或Ant样式的路径模式,而不是匹配所有路径的任何路径

    @Bean
    public Docket apiDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.vojtechruzicka"))
                .paths(PathSelectors.ant("/v2/**"))
                .build()
                .apiInfo(getApiInfo());
    }

    如果内置选项对您来说还不够,您可以随时为apis()paths()提供自己的谓词。忽略某些类或方法的另一种方法是使用@ApiIgnore注释它们。

    (八)使用JSR-303注解

    JSR 303:Bean Validation  允许您注释Java类的字段以声明约束和验证规则。您可以使用以下规则注释单个字段: - 不能为空,最小值,最大值,正则表达式匹配等。

    public class Person {
        @NotNull
        private int id;
    
        @NotBlank
        @Size(min = 1, max = 20)
        private String firstName;
    
        @NotBlank
        @Pattern(regexp ="[SOME REGULAR EXPRESSION]")
        private String lastName;
    
        @Min(0)
        @Max(100)
        private int age;
    
        //... Constructor, getters, setters, ...
    }

    这是一种已经广泛使用的常见做法。好消息是,SpringFox可以根据这些注释生成Swagger文档,因此您可以利用项目中已有的内容而无需手动编写所有约束!它非常有用,因为您的API的消费者知道他们应该为您的API提供的值的限制以及期望的值。如果没有包含这样的注释,我们的人员模型的生成文档看起来很简单,除了字段名称及其数据类型之外什么也没有。

    招摇的UI模型平原

    使用来自JSR-303注释的数据,它看起来会更好:

    JSR-303-招摇

    不幸的是,基于JSR-303的文档无法开箱即用,您需要一个额外的依赖:

    //MAVEN
    <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-bean-validators</artifactId>
       <version>2.9.2</version>
    </dependency>
    
    //GRADLE
    compile "io.springfox:springfox-bean-validators:2.9.2"

    并且您需要在swagger配置类之上导入BeanValidatorPluginsConfiguration配置文件:

    @Configuration
    @EnableSwagger2
    @Import(BeanValidatorPluginsConfiguration.class)
    public class SpringFoxConfig {
      ...
    }

    (九)将Swagger Core注释添加到模型类中

    使用JSR-303的优点是,如果您已经使用它们,您可以毫不费力地获得额外的文档信息,而无需更改任何代码。问题是目前,SpringFox不显示注释中指定的验证消息。此外,您可能需要记录一些更复杂的约束。在这种情况下,您可以使用Swagger Core注释,它允许您指定其他信息,例如描述。用这些注释注释的Person类可以看起来像这样。

    @ApiModel(description = "Class representing a person tracked by the application.")
    public class Person {
        @ApiModelProperty(notes = "Unique identifier of the person. No two persons can have the same id.", example = "1", required = true, position = 0)
        private int id;
        @ApiModelProperty(notes = "First name of the person.", example = "John", required = true, position = 1)
        private String firstName;
        @ApiModelProperty(notes = "Last name of the person.", example = "Doe", required = true, position = 2)
        private String lastName;
        @ApiModelProperty(notes = "Age of the person. Non-negative integer", example = "42", position = 3)
        private int age;
    
        // … Constructor, getters, setters, ...
    }

    在类级别,您使用@ApiModel注释并在字段级别@ApiModelProperty。当然,您可以与JSR-303注释混合搭配。 @ApiModelProperty的示例对于提供示例值非常有用,这不仅适用于用户的指导,而且还可以在使用Swagger UI作为REST客户端来测试服务时预填充请求有效负载。Position属性很方便指定属性在文档中显示的顺序。首先提供重要或必需的属性或属于一起的组属性是有用的。否则,属性将按字母顺序列出。

     

    (十)将Swagger Core注释添加到控制器类

    与使用Swagger核心注释注释模型类以提供其他元数据相同,您可以注释控制器及其方法和方法参数。

    • @Api描述了整个控制器
    • @ApiOperation用于方法级别的描述
    • @ApiParam用于方法参数

     

    @RestController
    @RequestMapping("/v2/persons/")
    @Api(description = "Set of endpoints for Creating, Retrieving, Updating and Deleting of Persons.")
    public class PersonController {
    
        private PersonService personService;
    
        @RequestMapping(method = RequestMethod.GET, produces = "application/json")
        @ApiOperation("Returns list of all Persons in the system.")
        public List getAllPersons() {
            return personService.getAllPersons();
        }
    
        @RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = "application/json")
        @ApiOperation("Returns a specific person by their identifier. 404 if does not exist.")
        public Person getPersonById(@ApiParam("Id of the person to be obtained. Cannot be empty.")
                                        @PathVariable int id) {
            return personService.getPersonById(id);
        }
    
        @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
        @ApiOperation("Deletes a person from the system. 404 if the person's identifier is not found.")
        public void deletePerson(@ApiParam("Id of the person to be deleted. Cannot be empty.")
                                     @PathVariable int id) {
            personService.deletePerson(id);
        }
    
        @RequestMapping(method = RequestMethod.POST, produces = "application/json")
        @ApiOperation("Creates a new person.")
        public Person createPerson(@ApiParam("Person information for a new person to be created.")
                                       @RequestBody Person person) {
            return personService.createPerson(person);
        }
    
        @Autowired
        public void setPersonService(PersonService personService) {
            this.personService = personService;
        }
    }

    现在您的文档还应包含所提供的描述:

    招摇控制器-doc的

    请注意,我们的控制器和域类现在受到Swagger特定注释的困扰。可读性受到很大影响,因为重要的信息在大量的漏洞中丢失了。更糟糕的是 - 当您更改代码时,以这种方式编写的文档不会更新,您需要记住手动更改消息。这会增加您的文档不同步的风险,因此不值得信任。最好包括一些不明显的基本信息,而这些信息尚未被自动生成的信息很好地涵盖。具有参数的描述性名称以及JSR-303注释通常可以记录大部分所需信息。

    (十一)从属性文件加载描述

    直接在注释中提供描述并不是很优雅。它可能占用大量空间,污染您的代码。你不能真正支持多种语言。如果要修复拼写错误或对文档进行一些更改,则需要重新构建并重新部署整个应用程序。根据环境,您不能拥有不同的值。不是很灵活。幸运的是,Spring提供了Property占位符的概念。简而言之,它允许您提供占位符$ {placeholder}而不是硬编码值。然后在.properties文件中定义占位符的值。Spring从属性加载数据并注入它而不是占位符。很酷的是,您可以为每种语言提供多个属性文件。您可以在不同的环境中提供不同的属性文件。

    SpringFox在一些注释中支持这种机制。这是一种很好的方法,可以将文档与代码分离,并具有更大的灵活性。不幸的是,目前只支持一些注释。因此,例如在模型中,它们在方法级别(@ApiModelProperty)上支持它,但在类级别(@ApiModel)上不支持它。

    要完成这项工作,您需要:

    1. 创建属性文件,例如swagger.properties
    2. 输入您想要的消息作为键值对,其中键将用作占位符 - 例如person.id =此人的唯一标识符
    3. 而不是注释文本插入占位符 - 例如$ {person.id}
    4. 在类级别注册配置中的属性文件 - 例如。 @PropertySource( “类路径:swagger.properties”)

    结论

    SpringFox是一个有用的工具,它可以根据您的Spring控制器和模型类自动生成Swagger文档。它还可以识别JSR-303注释,因此您还要记录模型类的所有约束。它还可以使用核心的swagger类,例如@ApiModelProperty。但要小心,因为这会使你的代码充满了大量特定的注释。只有在SpringFox无法推断信息本身时才使用它们总是更好。仅在需要添加某些描述时才使用它们,其中类,属性和方法名称不能自我解释。再说一遍,你的API可能是一个红色标志,说明你的API是神秘的还是太复杂了。如果您保留由SpringFox自动生成的大部分文档,您可以确保它始终是最新的。除此以外,在代码中进行更改时,您需要非常小心地更新Core Swagger注释。如果您的文档和代码不匹配,用户将失去对您的API文档的信任,并且此类文档几乎无用。

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    声明: 本文转自      Vojtech Ruzicka的编程博客

     

  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1046 Shortest Distance (20)
    1061 Dating (20)
    1041 Be Unique (20)
    1015 Reversible Primes (20)(20 分)
    pat 1027 Colors in Mars (20)
    PAT 1008 Elevator (20)
    操作系统 死锁
    Ajax的get方式传值 避免& 与= 号
    让IE浏览器支持CSS3表现
  • 原文地址:https://www.cnblogs.com/SunArmy/p/9992705.html
Copyright © 2011-2022 走看看