[Microservices] Springboot integrates swagger in multiple modes and uses them in detail

Table of contents

I. Introduction

1.1 Write API documentation

1.2 Use some online debugging tools

1.3 postman

1.4 swagger

2. Introduction to swagger

2.1 Background

2.2 Advantages and disadvantages of swagger

2.2.1 Advantages of swagger

2.2.2 Disadvantages of swagger

2.2.3 swagger usage scenarios

3. Several integration modes commonly used by swagger

3.1 swagger2

3.2 knife4j

3.2.1 knife4j features

3.2.2 knife4j release notes

3.3 Springdoc

3.3.1 Introduction to SpringDoc

Four, springboot integrated swagger multiple mode cases

4.1 springboot integrates swagger2

4.1.1 Add the following core dependencies

4.1.2 Configuration file

4.1.3 Custom swagger configuration class

4.1.4 Custom test interface

4.1.5 Custom entity class

4.1.6 Access swagger interface

4.2 springboot integration knife4j

4.2.1 Introducing core dependencies

4.2.2 Custom configuration class

4.2.3 Add test interface

4.2.4 Custom Entity Classes

4.2.5 Accessing the UI interface

4.3 springboot integration springdoc

4.3.1 Add core dependencies

4.3.2 Core configuration files

4.3.3 Custom configuration class

4.3.4 Custom test interface

4.3.5 Accessing the UI interface

5. Write at the end


I. Introduction

In today's development mode with faster and faster iterative speed, more and more projects are developed using springboot as the server-side framework. After the back-end API development and self-test are completed, how can the front-end colleagues connect with you quickly and efficiently? What about APIs? You may know the following ways:

1.1 Write API documentation

This is a relatively traditional approach by many companies. Generally speaking, this method has high requirements for API developers, because the document writing process is relatively time-consuming, so before the API is developed, it is necessary to strictly control the parameters of the API. In order to reduce the event cost caused by changes in the docking process. Documents can be edited using traditional word documents or using markdown.

1.2 Use some online debugging tools

Nowadays, there are many online interface debugging tools on the market. You only need to deploy your API service to the server, and then you can remotely debug online.

1.3 postman

This is a relatively traditional but also very useful local debugging tool. For the team, the server developer can enter the API developed by A, and then share the API through the team sharing mode, and the front end can get it. The API list has been debugged and docked.

1.4 swagger

With the increasing use of swagger and its popularity, especially in the agile development mode, it has more advantages and is accepted by many development teams. It only needs to integrate swagger dependencies on the server side, and then do simple configuration. It can be used immediately, and the cost of using and learning can be said to be almost zero.

2. Introduction to swagger

2.1 Background

After the current separation of the front and back ends has become the basic model for rapid product iteration, how to quickly complete the rapid joint debugging of the API and the front end has become a key factor in the phased release of the product. In this context, although the front end can complete its own functions through mock data Verification, but there is no real data joint debugging with the server, I always feel unreliable, but different teams have different joint debugging methods, which causes some teams to use simple tools, high joint debugging efficiency, and some complex , resulting in very low joint debugging efficiency, and even brought new learning costs.

In this context, how to improve the rapid joint debugging with API and reduce the learning cost of team members as much as possible? So the emergence of swagger is a good solution to such a problem.

2.2 Advantages and disadvantages of swagger

2.2.1 Advantages of swagger

Using swager has the following advantages:

  • The integration is simple, just need to introduce a swagger jar package and do simple configuration;
  • Automatically generate documents, just use swagger's relevant annotations in the interface to annotate, and the corresponding interface documents can be generated;
  • Automatically update the document, because it is dynamically generated, so if you modify the interface, the document will automatically be modified accordingly (if you also update the annotation). In this way, I will not send the situation that I modified the interface but forgot to update the interface document;
  • Support online debugging, swagger provides the function of online call interface;

2.2.2 Disadvantages of swagger

Although swagger brings convenience to API management, there are still some shortcomings,

  • You cannot create test cases, but only provide a simple online debugging. If you want to store test cases, you need to choose other tools, such as postman, or export yaml files through swagger for storage;
  • Some basic coding standards need to be followed in the program. For example, if you need to return a json data, and this data may be in a Map format, then we cannot mark the description of each field of the returned data in this Map format at this time, and if it is an entity class, it needs to be an entity class The attributes in are marked with specific annotations. The problem caused by this is obviously that the entity class of the program looks a little messy, not neat enough, and redundant;
  • It is impossible to dynamically refresh the API. If you forget to restart a certain interface currently being used by the front-end after changing it locally, the front-end may still use the old interface;
  • There is a certain degree of security problem, and too much information will be exposed on the UI interface. For example, in a certain interface, the front end may only need 3 required parameters, but on the UI interface of swagger, all the field information of the object will be displayed. Fill it in, so it looks messy and redundant;

2.2.3 swagger usage scenarios

Not all projects are suitable for using swagger. For example, some older projects may cause huge time and labor costs if they are strongly integrated due to version issues. There are also some projects that have particularly high security requirements, and are not allowed to be arbitrary. It is not appropriate to use swagger to expose the API of the server to the external network. However, judging from the current trend, the use of swagger can still improve the overall development and docking efficiency. Here are some scenarios summarized below for reference:

  • For projects with small business volume, rapid function iteration, and tight development time requirements, you can consider using swagger;
  • Low security requirements, or only used in the company's intranet environment, or only used in the development stage, this can also be considered to use swagger in the development stage;
  • The server framework is springboot, and springboot currently occupies the mainstream of the microservice framework, so it is more convenient to integrate with swagger;

3. Several integration modes commonly used by swagger

Taking the integration of springboot and swagger as an example, it provides a variety of ways to use. The following are the commonly used ones. Mastering these should be enough to deal with most scenarios.

3.1 swagger2

This is an original method, and it is also a method often used by many small teams. It can be used by directly introducing the basic dependent jar package of swagger. The integration with springboot mainly includes the following packages:

  • springfox-swagger2;
  • springfox-swagger-ui;

3.2 knife4j

The predecessor of Knife4j is swagger -bootstrap-ui, and the predecessor swagger-bootstrap-ui is a pure swagger-ui ui skin project;

The original intention of the project was to write an enhanced version of swagger's front-end ui, but with the development of the project, facing more and more personalized needs, the back-end Java code had to be written to meet new needs.

Between versions 1.8.5 and 1.9.6 of swagger-bootstrap-ui, the back-end Java code and Ui are mixed in a Jar package for developers to use. Although this method is very convenient for integrating swagger, it only needs to introduce the jar package, but it seems a bit bloated under the microservice architecture. Therefore, the project was officially renamed knife4j, named knife4j in the hope that she can be as small, lightweight, and powerful as a dagger. The name change also hopes to make her a general solution for Swagger interface documents, not just focus on the front-end Ui front-end.

3.2.1 knife4j features

  • All the features of swagger-bootstrap-ui will be concentrated in the knife4j-spring-ui package, and the subsequent planning will also meet the more personalized needs of developers;
  • The main change is that the relevant class package path of the project is replaced with com.github.xiaoymin.knife4j prefix, and developers need to replace the package path when using enhanced annotations;
  • The back-end Java code and ui package are separated into jar packages of multiple modules to facilitate the use of enhanced document annotations under the current microservice architecture (using the SpringCloud microservice project, only the jar package of the UI needs to be integrated at the gateway layer That's it, so separate the front and back ends);
  • knife4j continues to use the version number of swagger-bootstrap-ui, the first version starts from 1.9.6, please refer to the documentation for the usage method (excerpted from the official introduction of knife4j);

3.2.2 knife4j release notes

The main versions of knife4j are basically as follows

1.9.6 Blue skin style, start to change name, add more backend modules
2.0~2.0.5 Ui rewritten, the underlying version of the springfox framework is 2.9.2
2.0.6~ The springfox framework version is upgraded to 2.10.5, and the OpenAPI specification is v2
3.0~ The underlying dependency springfox framework version is upgraded to 3.0.3, and the OpenAPI specification is v3

3.3 Springdoc

Compared with the first two, springdoc is currently very popular. First, this framework is relatively new, and the code maintenance and update speed is fast, and when it is integrated with the springboot project, it also provides a security plug-in, which can improve the usage to a certain extent. safety. The address of git is: springdoc source code address

3.3.1 Introduction to SpringDoc

SpringDoc is an API document generation tool that can be used in conjunction with SpringBoot. Based on OpenAPI 3, it currently has 1.7K+ Stars on Github. The update release is still very diligent. It is a better Swagger library! It is worth mentioning that SpringDoc not only supports Spring WebMvc projects, but also Spring WebFlux projects, and even Spring Rest and Spring Native projects. In short, it is very powerful. The following is a SpringDoc architecture diagram.

Four, springboot integrated swagger multiple mode cases

The above has theoretically understood several commonly used ways of using swagger, and then will give detailed explanations through actual cases.

4.1 springboot integrates swagger2

Pre-preparation, build the springboot project, the directory structure is as follows

4.1.1 Add the following core dependencies

The following are only core dependencies, you can add them as appropriate according to your own situation

<dependencies>

        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--swagger API获取-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

        <!--swagger-ui API获取-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>


    </dependencies>

4.1.2 Configuration file

Using this method does not require too much configuration, only one port is configured here

server.port=8088

4.1.3 Custom swagger configuration class

This class is the most important configuration in the whole integration process, mainly including:

  • Define the scanning path of the interface;
  • The swagger-ui interface displays information;
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.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)
                //用于生成API信息
                .apiInfo(apiInfo())
                //select()函数返回一个ApiSelectorBuilder实例,用来控制接口被swagger做成文档
                .select()
                //用于指定扫描哪个包下的接口
                .apis(RequestHandlerSelectors.basePackage("com.congge.controller"))
                //选择所有的API,如果你想只为部分API生成文档,可以配置这里
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                //用来自定义API的标题
                .title("SpringBoot项目SwaggerAPIAPI测试")
                //用来描述整体的API
                .description("SpringBoot项目SwaggerAPI描述信息")
                //创建人信息
                .contact(new Contact("测试人员","http://localhost:8082/swagger-ui.html","[email protected]"))
                //用于定义服务的域名
                //.termsOfServiceUrl("")
                .version("1.0") //可以用来定义版本
                .build();
    }

}

4.1.4 Custom test interface

To customize a test interface, it can be said that in order to enable the interface in the project to be debugged in swagger-ui, the most important thing is to add this annotation to the class: @Api, some annotations on other methods, you can refer to the official document Just configure it;

//http://localhost:8088/swagger-ui.html  主页访问地址

@RestController
@Api(tags = "UserController", description = "UserController | 测试swagger")
public class UserController {

    @GetMapping("getById")
    @ApiOperation(value="getById 方法", notes="getById,根据ID获取账户信息")
    public User getById(){
        return new User("001","jerry","123456");
    }

    @PostMapping("/save")
    public String saveUser(UserRequest userRequest){
        User user = new User();
        BeanUtils.copyProperties(userRequest,user);
        return "success";
    }

}

4.1.5 Custom entity class

In many cases, the parameters in the interface are object types. At this time, in order to let the front-end docking colleagues know the meaning of each parameter in the object, it is best to add some swagger annotations to the properties of each object according to the swagger specification. An example is provided below;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="用户登录表单对象",description="用户登录表单对象")
public class User implements Serializable {

    private static final long serialVersionUID = -2896873555774275129L;

    @ApiModelProperty(value = "用户ID",required = true,example = "001")
    private String id;

    @ApiModelProperty(value = "用户名称",required = true,example = "jerry")
    private String userName;

    @ApiModelProperty(value = "密码",required = true,example = "123456")
    private String passWord;

}

4.1.6 Access swagger interface

Start the service, and then visit the browser: http://localhost:8088/swagger-ui.html , as for how to debug and use, interested students can try it by themselves, it is relatively simple;

4.2 springboot integration knife4j

The above briefly introduces the background of knife4j. Next, let’s look at the detailed steps of integrating knife4j in springboot. First, create an empty springboot project in advance. The directory structure is as follows

4.2.1 Introducing core dependencies

Only two packages are needed for demonstration here, if you have other requirements, you can continue to add them;

    <dependencies>
        <!-- Spring Boot Web依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>

    </dependencies>

4.2.2 Custom configuration class

This is similar to the integration of swagger2 above. You need to customize a class that defines the display information of the UI interface and the package path where the scanned interface class is located.

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 Knife4jConfiguration {

    @Bean(value = "defaultApi2")
    public Docket defaultApi2() {
        String groupName="3.X版本";
        Docket docket=new Docket(DocumentationType.OAS_30)
                .apiInfo(new ApiInfoBuilder()
                        .title("这是knife4j API ")
                        .description("这是knife4j,记录了API相关的出参和入参信息")
                        .termsOfServiceUrl("http://yaomaoyang.com")
                        .contact(new Contact("congge","http://127.0.0.1","[email protected]"))
                        .version("3.0")
                        .build())
                //分组名称
                .groupName(groupName)
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("com.congge.controller"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }
}

4.2.3 Add test interface

In order to allow the interface to be displayed on the UI interface, the most important thing is to add this @Api annotation on the class. Other annotations can be marked on the interface class method as needed, similar to using swagger above;

@RestController
@RequestMapping(value = "/user")
@Api(tags = "用户管理API")
public class UserController {

    /**
     * 根据ID获取账户信息
     * @param id
     * @return
     */
    @GetMapping(value = "/getById")
    @ApiImplicitParam(name = "name",value = "姓名",required = true)
    @ApiOperation("根据ID获取账户信息")
    public User test(@RequestParam("id") String id){
        User user = new User();
        user.setId(id);
        user.setPassWord("123456");
        user.setUserName("jerry");
        return user;
    }

}

4.2.4 Custom Entity Classes

If the parameters received in some interfaces are an object, in order to allow other students to understand the parameters in the object, you can add annotations provided by knife4j to the object. Here is an example

@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="用户登录表单对象",description="用户对象参数")
public class User implements Serializable {

    private static final long serialVersionUID = -2896873555774275129L;

    @ApiModelProperty(value = "用户ID",required = true,example = "001")
    private String id;

    @ApiModelProperty(value = "用户名称",required = true,example = "jerry")
    private String userName;

    @ApiModelProperty(value = "密码",required = true,example = "123456")
    private String passWord;

}

4.2.5 Accessing the UI interface

Start the project, and then access the interface through this address: http://localhost:8082/doc.html to see if the interface looks more professional in style;

4.3 springboot integration springdoc

Compared with the first two, springdoc appeared later, but at present, its popularity seems to be better. On the one hand, it has the basic functions of swagger, and at the same time, it has certain guarantees on the security of access. , Let's look at the specific integration steps, create a springboot project in advance, the directory structure is as follows:

4.3.1 Add core dependencies

 Other dependencies can be quoted as appropriate according to their own circumstances

    <dependencies>
        <!-- Spring Boot Web依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- springdoc swagger ui -->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-javadoc</artifactId>
            <version>1.7.0</version>
        </dependency>
    </dependencies>

4.3.2 Core configuration files

Add the following configurations to the application.yml file. These configurations are well-known and will not be explained here. Among them:

api-docs.path: /v3/api-docs This configuration is to obtain the address of the yml document of the interface

There are richer configurations in it, you can refer to the information on the Internet, there are more detailed instructions, for example, you can also configure the pre-path to open the UI interface, etc.;

# springdoc配置
springdoc:
  # 分组配置
  group-configs:
    - group: 用户管理
      packages-to-scan: com.congge.controller
      paths-to-match: /users/**
    - group: 角色管理
      packages-to-scan: com.congge.controller
      paths-to-match: /roles/**
  api-docs:
    enabled: true
    path: /v3/api-docs

server:
  port: 8087

4.3.3 Custom configuration class

Custom configuration can group and manage various APIs in the project, and inject them into the spring container in the form of beans;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.servers.Server;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;

@Configuration
public class OpenApiConfig {

    /*@Bean
    public OpenAPI springShopOpenAPI() {
        return new OpenAPI()
                .info(new Info().title("Springdoc OAS3.0 - RESTful API")
                        .description("Springdoc OAS3.0 构建RESTful API")
                        .version("1.0")
                        .license(new License().name("Apache 2.0").url("http://springdoc.org")))
                .servers(Arrays.asList(
                        new Server().description("开发环境").url("http://localhost:8087")
                ))
                .externalDocs(new ExternalDocumentation()
                        .description("SpringShop Wiki Documentation")
                        .url("https://springshop.wiki.github.org/docs"));
    }*/

    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .components(new Components())
                .info(new Info()
                        .title("User Manager API")
                        .description("用户管理系统API.")
                        .version("1.0"));
    }

    @Bean
    public GroupedOpenApi frontApi() {
        return GroupedOpenApi.builder()
                .group("frontApi")
                .pathsToMatch(new String[]{"/users/**", "/roles/**"})
                .packagesToExclude("com.congge.controller")
                .build();
    }
}

4.3.4 Custom test interface

Note that the annotation on the interface class, @Tag, is the key to recognition on the UI interface;

//http://localhost:8087/swagger-ui/index.html?urls.primaryName=%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86

@Tag(name = "用户管理", description = "用户管理FrontApi")
@RestController
@RequestMapping("/users")
public class UserController {

    /**
     * 查询用户详细信息
     *
     * @param id 用户ID
     * @return 用户信息
     */
    @GetMapping("/get")
    public UserInfo getUser(@RequestParam String id) {
        return new UserInfo();
    }

}

@Data
@Schema(description = "用户返回实体对象")
class UserInfo {
    @Schema(description = "用户名称")
    private String userName;
    @Schema(description = "用户密码")
    private String passWord;
}

4.3.5 Accessing the UI interface

Start the project and access the interface address: http://localhost:8087/swagger-ui/index.html , you can see the following effect, which is similar to the above two when debugging the interface on the UI interface;

5. Write at the end

This article summarizes in detail the various ways of using springboot to integrate swagger, hoping to bring help to your daily development. This is the end of this article, thank you for watching!

Guess you like

Origin blog.csdn.net/congge_study/article/details/130996112