preface

There are very few effective articles about the use of Swagger 3 in Spring Boot. Most of the articles published by Baidu are about Swagger 2.X or Swagger 3. So I felt it was important to document some of the things I’ve done with Swagger 3 (OpenAPI 3.0) in the hope of helping as many people as possible.

OpenAPI and Swagger

OpenAPI profile

The OpenAPI Specification (OAS) defines a standard, programming language-neutral API description specification for RESTful apis. It allows humans and computers to discover and understand services without looking at source code, documentation, or by monitoring network traffic. Using OpenAPI correctly makes it easier for consumers to understand and interact with services with little or no understanding of their implementation logic.

For the full OpenAPI Specification, see OpenAPI Specification

Introduction of Swagger

OpenAPI is a specification, Swagger is a specification, is the predecessor of OpenAPI specification. The Swagger specification was renamed OpenAPI after it was donated to the Linux Foundation in 2015, and the latest specification is defined as OpenAPI 3.0. So now Swagger 3.0 is OpenAPI 3.0.

Commonly referred to as Swagger is the name of a suite of tools developed and maintained by SmartBear Software to implement the OpenAPI specification. The Swagger tool contains a combination of open source, free, and commercial tools that can be developed throughout the API lifecycle.

For more information on the Difference Between the two, see: What Is the Difference Between Swagger and OpenAPI?

Swagger official: Swagger. IO /

In a word: OpenAPI is a specification, and Swagger is the suite of tools used to implement the specification.

SpringFox and SpringDoc

SpringFox profile

SpringFox is an (unofficial) project maintained by the Spring community to help users integrate Swagger 2 into Spring. It is often used in Spring to help developers generate documentation and can be easily used in Spring Boot.

SpringFox 3.0 related features

  • Support for Spring 5, Webflux (mapping support only requested, functional endpoints not yet supported), Spring Integration
  • Supplement the official autowiring in Spring Bootspringfox-boot-starterIn the future, only onedependency
  • Better specification compatibility with 2.0
  • Support OpenApi 3.0.3
  • Light reliance on Spring-plugin, swagger-core
  • The existing Swagger 2 annotations continue to be valid and enrich the OpenAPI 3.0 specification

Making: github.com/springfox/s…

SpringDoc profile

SpringDoc is also an (unofficial) project maintained by the Spring community to help users integrate Swagger 3 into Spring.

SpringDoc supports Swagger page Oauth2 login, which is definitely a better choice for longer support times than SpringFox. However, the development of Swagger 2 in China is relatively slow, and I seldom see too many useful documents. Basically, the content of Swagger 2 released by Baidu is all about Swagger 2, but the official website documents also provide detailed usage instructions. SpringDoc uses Swagger 3 (OpenAPI 3), but Swagger 3 is not compatible with Swagger 2’s annotations and is not easy to migrate.

Migrate from SpringFox to SpringDoc

Migrating from SpringFox is described in the documentation on the official website

I won’t go into too much detail here.

The following describes how to use Springfox to integrate Swagger 3 into Spring Boot and use Swagger 3 annotations.

Swagger 3 (OpenAPI 3)

Swagger 3 (OpenAPI 3

1. @OpenAPIDefinition

Describes tags, document information, security configuration, and external documentation for classes.

Common parameters:

  • info: Describes the document information. For details, see the following@Info
  • tags: Defines the tag list, as described below@Tag
  • servers: Target server connection list, see below for details@Server
  • externalDocs: Some external documentation for the API, see below for details@ExternalDocumentation

Example:

@tag (tags = {@tag (name = "user management ", description =" user module operation "), @tag (name = "role management ", Description = "role module operation ")}, info = @info (title =" user API documentation ", description = "user data management......" , version = "1.0.0", contact = @contact (name = "lanweihong", email = "[email protected]", Url = "https://www.lanweihong.com"), license = @ license (name = "Apache 2.0", Url = "http://www.apache.org/licenses/LICENSE-2.0.html")), the servers = {@ Server (description = "production environment Server", Url = "https://xxxx.com/api/v1"), @ Server (description = "test environment Server", url = "https://test.xxxx.com/api/v1")}, Security = @securityRequirement (name = "Oauth2"), externalDocs = @externalDocumentation (description =" url = "http://localhost/deploy/README.md" ) )
@Configuration
public class SwaggerConfig {
    / /...
} 
Copy the code

2. @Info

Document information, used in @Openapidefinition.

Common parameters:

  • title: App title
  • description: Application Description
  • contact: Contact information, see details@Contact
  • license: License information, see for details@License
  • versionVersion:

Example:

(info = @info (title = "user interface API documentation ", description =" user data management......") , version = "1.0.0", contact = @contact (name = "lanweihong", email = "[email protected]", Url = "https://www.lanweihong.com"), license = @ license (name = "Apache 2.0", Url = "http://www.apache.org/licenses/LICENSE-2.0.html")))
@Configuration
public class SwaggerConfig {
    / /...
}
Copy the code

3. @Tag

Tags that describe or define an operation are used on a class or method. You can also use tags in @openapidefinition.

Common parameters:

  • nameName:
  • descriptionDescription:

Example:

Used of classes:

@tag (name = "user management ")
@RestController
public class UserController {
    / /...
}
Copy the code

Define tags in @openapidefinition:

@tag (tags = {@tag (name = "user management ", description =" user module operation "), @tag (name = "role management ", Description = "role module operation ")})
@Configuration
public class SwaggerConfig {
    / /...
}
Copy the code

It should be noted that the @Tag configuration does not work on Controller when used with Springfox integration and is not shown in the Swagger UI. @tag annotation not work as expected on the Controller class.

It is not fixed yet, the solution is to use the 2.x version of annotations instead:@API (tags = "User Management ") 。

This problem does not exist in Springdoc. When generating API documents from Springdoc, @Tag is used normally and displayed normally in Swagger UI

4. @Contact

This parameter is used in @info to describe contact information.

Common parameters:

  • name: Unique name (individual/organization)
  • url: Indicates the URL pointing to the contact information
  • email: the email address

Example:

@OpenAPIDefinition( info = @Info( contact = @Contact( name = "Li.chen", email = "mail", url = "www" ) ) )
@Configuration
public class SwaggerConfig {
    / /...
}
Copy the code

5. @License

Used to defy license information, used in @info.

Common parameters:

  • name: License name
  • url: indicates the URL pointing to the license

Example:

Servers = {@server (description = "Server ", URL = "https://xxxx.com/api/v1"), @ Server (description = "test environment Server", url = "https://test.xxxx.com/api/v1")})
@Configuration
public class SwaggerConfig {
    / /...
}
Copy the code

6. Server

This parameter is used to configure the target host, used in @Openapidefinition.

Common parameters:

  • url: Host address
  • description: Host description

Example:

Servers = {@server (description = "Server ", URL = "https://xxxx.com/api/v1"), @ Server (description = "test environment Server", url = "https://test.xxxx.com/api/v1")})
@Configuration
public class SwaggerConfig {
    / /...
}
Copy the code

7. @Operation

Used to describe the purpose of a method; used in a method.

Parameters:

  • summary: method outline, a brief introduction to the method, recommended in 120 characters
  • description: Method description, usually very long content
  • hidden: Whether to hide

Example:

@operation (summary = "query user list ", description =" return all user data ")
@GetMapping("/users")
public String getUseList(a) {
    return "";
}
Copy the code

8. @Parameter

Used to describe method parameters, used on method parameters.

Parameters:

  • name: Specifies the parameter name
  • in: Parameter position, optionalquery,header,path 或 cookie, the default value is empty, indicating that the command is ignored
  • description: Parameter Description
  • required: Mandatory or not. The default value isfalse

Example:

@operation (summary = "delete user ")
@DeleteMapping("/users/{username}")
public JsonResult<UserVO> deleteUserByName(
        @parameter (name = "username", in = parameterin. PATH, description = "username", Required = true) 
        @PathVariable("username") String userName
    ) {
    // TODO
    return JsonResult.ok();
}
Copy the code

9. @ApiResponse

Used to indicate a response, as in @apiresponses.

Parameters:

  • responseCode: INDICATES the HTTP response code
  • descriptionDescription:

Example:

@operation (summary = "Query user by user name ", description =" Query user details by user name ")
@apiresponses (value = {@apiresponse (responseCode = "200", description = "successful "), @apiResponse (responseCode = "404", Description = "user does not exist ", content = @content)})
@GetMapping("/{username}")
public JsonResult<UserVO> getUserByName(@parameter (description = "user name ", required = true) @PathVariable("username") String userName) {
    // TODO
    return JsonResult.ok();
}
Copy the code

10. @ApiResponses

Used to describe a set of response information, such as a request that may return multiple responses, such as a success message (200) or a possible throw exception (400), used in a method.

Parameters:

  • value:@ApiResponseAn array of

Refer to @apiResponse above for examples.

11. @Schema

Used to describe data object information or data object attributes, such as various POJO classes and attributes, for classes or class attributes.

Parameters:

  • name: Attribute name
  • description: Attribute Description
  • required: Is it necessary
  • minLength: Indicates the minimum length of a character
  • maxLength: Indicates the maximum length of a character

Example:

@schema (description = "user entity ")
public class UserVO {

    @schema (description = "user name ")
    private String userName;

    @schema (description = "mailbox ")
    private String email;

    // Getter And Setter ...
}
Copy the code

It’s worth noting that when using Springfox integration,@SchemaConfiguration on the class does not generate its configuration information in the Swagger UI, but the configuration on the class attributes is normal. Configuration is available on a class@apiModel (description = "user parameter object ")To replace.

This problem does not exist with Springdoc integration, and the @Schema configuration is fine on both classes and properties when Springdox integration is used.

12. @Hidden

Used to hide a resource, class, or attribute on a class, method, or attribute.

Example:

@RestController
@RequestMapping("/api/roles")
// Hide the entire RoleController
@Hidden
public class RoleController {

    @GetMapping("")
    public JsonResult<String> queryRoleList(a) {
        returnJsonResult.ok(); }}Copy the code

These are the only annotations that are commonly used. For more, see the OpenAPI Specification.

The following tutorial uses Springfox integration, which may not be particularly well supported for new annotations. Some annotations don’t work when added, so not all of the code in the following configuration uses new annotations. Therefore, I still recommend using Springdoc to integrate the generated documents.

Swagger 3 (OpenAPI 3)

Add the dependent

Edit pom.xml to add dependencies:

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

Add the Swagger configuration class

  1. Add Swagger property configuration class to encapsulate Swagger configuration parameters:
@ConfigurationProperties(prefix = "spring.swagger")
@Data
public class SwaggerProperties {
    private Boolean enable;
    private String groupName;
    private String basePackage;
    private String version;
    private String title;
    private String description;
    private String contactName;
    private String contactEmail;
    private String contactUrl;
}
Copy the code
  1. Add Swagger configuration class, add annotations@EnableOpenApi:
@Configuration
@EnableOpenApi
@EnableConfigurationProperties(value = {SwaggerProperties.class})
public class SwaggerConfig {
    
    SwaggerProperties swaggerProperties;

    @Autowired
    public void setSwaggerProperties(SwaggerProperties swaggerProperties) {
        this.swaggerProperties = swaggerProperties;
    }

    /**
     * API
     * @return* /
    @Bean
    public Docket adminApi(a) {
        // OAS_30: different from V2 (OpenAPI Specification)
        return new Docket(
                // Use OpenAPI 3.0
                DocumentationType.OAS_30)
                .enable(swaggerProperties.getEnable())
                / / API information
                .apiInfo(getAdminApiInfo())
                / / API group
                .groupName(swaggerProperties.getGroupName())
                .select()
                // Listen on the interface of a packet
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
                // Listen on all interfaces
                // .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    /** * API information *@return* /
    private ApiInfo getAdminApiInfo(a) {
        return new ApiInfoBuilder()
                // Document title
                .title(swaggerProperties.getTitle())
                // Document description
                .description(swaggerProperties.getDescription())
                // Contact information
                .contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactUrl(), swaggerProperties.getContactEmail()))
                // Document version.version(swaggerProperties.getVersion()) .build(); }}Copy the code

Use the Swagger 3

  1. Add the Controller:
@RestController
@RequestMapping("/api/users")
/ / @ Tag annotation is not effective, seems to be a BUG, related issues:https://github.com/springfox/springfox/issues/3668, therefore here using 2. X annotations @ Api
// @tag (name = "user admin ", description =" user admin ")
@API (tags = "User Management ")
public class UserController {

    @operation (summary = "query user list ", description =" return all user data ")
    @GetMapping("")
    public JsonResult<List<UserVO>> getUserList(@parameter (description = "user name ") @RequestParam(value = "username", required = false) String userName) {
        List<UserVO> result = new ArrayList<>();
        result.add(new UserVO("zhangsan"."[email protected]"));
        result.add(new UserVO("lisi"."[email protected]"));
        return JsonResult.ok(result);
    }

    @operation (summary = "Query user by user name ", description =" Query user details by user name ")
    @apiresponses (value = {@apiresponse (responseCode = "200", description = "successful "), @apiResponse (responseCode = "404", Description = "user does not exist ", content = @content)})
    @GetMapping("/{username}")
    public JsonResult<UserVO> getUserByName(@parameter (description = "user name ", required = true) @PathVariable("username") String userName) {
        // TODO
        return JsonResult.ok();
    }

    @operation (summary = "new user ")
    @PostMapping("")
    public JsonResult<UserVO> addUser(@Parameter(required = true) @Valid @RequestBody UserParam param) {
        // TODO
        return JsonResult.ok();
    }

    @operation (summary = "modify user ")
    @PutMapping("")
    public JsonResult<UserVO> updateUser(@parameter (description = "user Parameter ", required = true) @Valid @RequestBody UserParam param) {
        // TODO
        return JsonResult.ok();
    }

    @operation (summary = "delete user ")
    @DeleteMapping("/{username}")
    public JsonResult<UserVO> deleteUserByName(@parameter (name = "username", in = parameterin. PATH, description = "username", Required = true) @PathVariable("username") String userName) {
        // TODO
        return JsonResult.ok();
    }

    @Hidden
    @PostMapping("/test")
    public JsonResult<UserVO> testAddUser(@Valid @RequestBody UserParam userParam) {
        // TODO
        returnJsonResult.ok(); }}Copy the code
  1. Add the VO:
@Getter
@Setter
The @schema annotation does not apply to classes. Use @apiModel instead
@apiModel (description = "user entity ")
@ToString
public class UserVO {

    public UserVO(a) {}public UserVO(String userName, String email) {
        this.userName = userName;
        this.email = email;
    }

    @schema (name = "user name ", description =" user name ")
    private String userName;

    @schema (description = "mailbox ")
    private String email;
}
Copy the code
  1. Edit itemapplication.yml, add the following parameters:
# Custom Swagger configuration
    spring:
    swagger:
    enable: true
    groupName: The front end
    basePackage: com.lanweihong.springfox.swagger
    version: 1.0. 0
    title: The front end
    description: Development of the document
    contactName: lanweihong
    contactEmail: 986310747@qq.com
    contactUrl: blog.lanweihong.com
Copy the code
  1. If Spring Security is used in your project, add the following resources to release Swagger UI:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v3/api-docs"."/v3/api-docs/**"."/swagger-resources/**"."/swagger-ui/**"); }}Copy the code
  1. Start the project for testing.

Start the project, the browser visit: http://localhost:8080/swagger-ui/ (note: Swagger (2) X version to visit http://localhost:8080/swagger-ui.html, this is different from 3.0.) , you can see Swagger UI interface.

At this point, the use of SpringFox to integrate Swagger 3 in Spring Boot is complete.

The original link