This is the 25th day of my participation in the August Genwen Challenge.More challenges in August

OpenAPI and Swagger can often be found on the Internet. It is always silly to tell Swagger apart. Here is a brief introduction to Swagger OpenAPI. OpenAPI is the specification; Swagger is the tool to implement the specification. OpenAPI 3.0 is the first official release of the specification, as it was donated to the OpenAPI Initiative by SmartBear Software and renamed from the Swagger specification to the OpenAPI specification in 2015. OpenAPI is the official name of the specification. The development of the specification was driven by the OpenAPI Initiative, which involves more than 30 organizations from different sectors of the technology world — including Microsoft, Google, IBM, and CapitalOne. Smartbear Software, the company leading the development of the Swagger tool, is also a member of the OpenAPI Initiative and helped lead the development of the specification.

Integrate SpringBoot OpenApi

Make sure the SpringBoot version is at 2.x or higher.

OpenAPI rely on

Introduce OpenApi dependencies


<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
Copy the code

Writing configuration classes

Write the configuration class and manually assemble @enableOpenAPI


@EnableOpenApi
@Configuration
public class OpenApiConfiguration {

    @Bean
    public Docket createRestApi(a) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .select()
                .apis(apis())
                .paths(PathSelectors.any())
                .build()
                .enable(true);
    }

    private ApiInfo apiInfo(a) {
        return new ApiInfoBuilder()
                .title("Project Name")
                .description("Project Description")
                .termsOfServiceUrl("Project Address")
                .version("API version")
                .license("Company license")
                .licenseUrl("Company license address")
                .build();
    }

    private Predicate<RequestHandler> apis(a) {
        return RequestHandlerSelectors.basePackage("Controller package path"); }}Copy the code

At this point SpringBoot has successfully integrated OpenAPI. It should be mentioned that OpenAPI can generate OpenAPI not only by scanning the path of the Controller package, but also by scanning @apiOperation.

Transform optimization

The above example is hard coded, so the code cannot be reused, and the code needs to be changed every time the configuration is updated. For example, when our project is developing or testing the environment, we want to use OpenAPI normally, but need to disable OpenAPI in the production environment. From an engineering perspective, it is common practice to try to change the configuration rather than the code. Based on this, we can modify the above code with the help of SpringBoot configuration capabilities.

  1. Added OpenApi configuration class

@Data
@Component
@ConfigurationProperties(prefix = "example.web.swagger")
public class SwaggerProperties {
    /** * Whether swagger3 is enabled */
    private Boolean enable = false;
    /** * Scan packet path, can not be specified, the system will automatically scan {@link io.swagger.annotations.ApiOperation}
     */
    private String basePackage;
    /** ** title */
    private String title;
    /** * Application description */
    private String description;
    /** * service address */
    private String serviceUrl;
    /** * version, default V1.0.0 */
    private String version = "V1.0.0";
    /** * license */
    private String license;
    /** * licenseUrl */
    private String licenseUrl;
}
Copy the code
  1. Configure replacement hard coding

@Slf4j
@Configuration
@EnableOpenApi
public class OpenApiConfiguration {

    @Resource
    private SwaggerProperties swaggerProperties;

    @Bean
    public Docket createRestApi(a) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .select()
                .apis(apis())
                .paths(PathSelectors.any())
                .build()
                .enable(isEnable());
    }

    private Boolean isEnable(a) {
        Boolean enable = swaggerProperties.getEnable();
        if (enable) {
            log.info("\nEnable Swagger3...");
        }
        return enable;
    }

    private ApiInfo apiInfo(a) {
        return new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .termsOfServiceUrl(swaggerProperties.getServiceUrl())
                .version(swaggerProperties.getVersion())
                .license(swaggerProperties.getLicense())
                .licenseUrl(swaggerProperties.getLicenseUrl())
                .build();
    }

    private Predicate<RequestHandler> apis(a) {
        String basePackage = swaggerProperties.getBasePackage();
        ApiOperation is used by default. If a packet scan path is configured, the configured packet scan path is used
        returnStrings.isNullOrEmpty(basePackage) ? withMethodAnnotation(ApiOperation.class) : basePackage(basePackage); }}Copy the code

With this simple modification, OpenApi can be configured entirely as a configuration file

  1. Sample configuration
example:
  web:
    swagger:
      enable: true
      title: Demo OpenAPI
      description: Demo OpenAPI
      base-package: com.example.controller
Copy the code

OpenAPI common comments

Here we demonstrate the use of annotations by using code

  1. Entity class

The VO entity class of the user needs to annotate @APIModel and explain the function of the class. The function of the attribute should be resolved through @APIModelProperty, and whether the attribute can be null should be specified through the value of required. The use case value of the attribute can be explained through example


@Data
@apiModel (" User info ")
public class UserVO {

    @apiModelProperty (value = "user id", Required = true, example =" asDF124 ")
    private String userId;

    @APIModelProperty (value = "user name ", Required = true)
    private String username;

    @apiModelProperty (value = "user age ")
    private Integer age;
}
Copy the code
  1. The controller class

This is mainly demonstrated through the user registration and user information interface. In addition, the function of annotating the class through @API; Use @apiOperation to explain the function of the interface. If the data passed is not an entity class but a primitive data type, you can use @apiParam to explain the role of the parameter

@RequestMapping("user")
@RestController
@API (tags = "User center ")
public class UserController {

    @apiOperation (" User registration ")
    @PostMapping
    public R<Void> register(@RequestBody UserVO userVO) {
        // todo 
        return R.ok();
    }

    @apiOperation (" Get user information by Id ")
    @GetMapping
    public R<UserVO> userInfo(@apiParam (value = "user id", Required = true) @RequestParam String userId) {
        // todo
        return R.ok(newUserVO()); }}Copy the code
  1. demo

To start the project, go to IP:PORT/swagger-ui/index.html to see the Swagger interface