SpringBoot 2.X Kotlin and Swagger 2 Generate API Documents

Posted by carolin on Wed, 15 May 2019 03:07:38 +0200

Here's a place to note that there are problems when testing WebFlux integration with Swagger 2. Looking at the official documentation, 2.9.2 is not yet integrated, so the jar introduced is spring-boot-starter-web, not spring-boot-starter-webflux.

Purpose of this chapter

Integrating document and interface testing platform in the project, using Swagger 2 can help us to write the latest API interface documents quickly. No longer need to worry about busy sorting out all kinds of information before the meeting, which indirectly improves the communication efficiency of team development.

Adding Swagger2 dependencies

Adding Swagger 2 dependencies to pom.xml

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

Create Swagger2 configuration

package io.intodream.kotlin04.config

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

/**
 * @description
 * Build a Swagger2 configuration file
 * @author Jwenk
 * @copyright intoDream.io Dream building technology
 * @email xmsjgzs@163.com
 * @date 2019-03-31,21:55
 */
@Configuration
@EnableSwagger2
class Swagger2Config {

    @Bean
    fun createRestApi(): Docket {
        return Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
    }

    private fun apiInfo(): ApiInfo {
        return ApiInfoBuilder()
                .title("Spring Boot2.X Kotlin Use in Swagger2 structure RESTFul APIs")
                .description("More SpringBoot2.X Kotlin Pay attention to the article:Cherish fish blog")
                .termsOfServiceUrl("https://www.intodream.io")
                .contact(Contact("Cherish fish", "https://www.tisnz.com", "xmsjgzs@163.com"))
                .version("1.0.0")
                .build()
    }
}

As shown in the code above, let Spring load the class configuration through the @Configuration annotation. Swagger2 is then enabled through the @Enable Swagger2 annotation.

After creating Docket beans through the createRestApi function, apiInfo() is used to create the basic information of the Api (which is displayed on the document page). The select() function returns an ApiSelector Builder instance to control which interfaces are exposed to Swagger for presentation. This example is defined by a specified scan package path. Swagger scans all APIs defined by Controller under the package and generates document content (except for requests specified by @ApiIgnore).

Writing Document Content

After completing the above configuration, Swagger will automatically generate API documents for us, but the automatically generated document display is not friendly. We usually need to add some additional information. At this time, we need to add instructions on the API through @ApiOperation annotations and @ApiImplicitParams and @ApiImplicitParam annotations to add instructions to the parameters.

package io.intodream.kotlin04.web

import io.intodream.kotlin04.model.Student
import io.swagger.annotations.Api
import io.swagger.annotations.ApiImplicitParam
import io.swagger.annotations.ApiOperation
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap

/**
 * @description
 *
 * @author Jwenk
 * @copyright intoDream.io Dream building technology
 * @email xmsjgzs@163.com
 * @date 2019-03-31,22:07
 */
@Api(value = "Student Information related interface", tags = ["Student"])
@RestController
@RequestMapping("/api/student")
class StudentController {

    private var repository : ConcurrentMap<String, Student> = ConcurrentHashMap<String, Student>()
    private val logger : Logger = LoggerFactory.getLogger(this.javaClass)

    @ApiOperation(value = "Keep a Student Information")
    @ApiImplicitParam(name = "student", value = "Student Detailed Entities student", required = true, dataType = "Student")
    @PostMapping("/")
    fun save(@RequestBody student: Student): Student? {
        logger.info("Request parameters:{}", student)
        return repository.put(student.id, student)
    }

    @ApiOperation(value = "Get a list of students")
    @GetMapping("/list")
    fun listStudent():List<Student> {
        val studentList = ArrayList<Student>(repository.values)
        logger.info("Return data:{}", studentList)
        return studentList
    }

    @ApiOperation(value = "Get detailed information of students through student number")
    @ApiImplicitParam(name = "studentId", value = "Student number", required = true, dataType = "String")
    @GetMapping("/info")
    fun studentInfo(@RequestParam studentId: String): Student? {
        val student : Student? = repository.get(studentId)
        logger.info("studentId:{}, Corresponding data:{}", student)
        return student
    }

    @ApiImplicitParam(name = "studentId", value = "Student number", required = true, dataType = "String")
    @ApiOperation(value = "Delete student information")
    @DeleteMapping("/")
    fun deleteStudent(@RequestParam studentId: String): String {
        logger.info("Delete Student Number:{}", studentId)
        repository.remove(studentId)
        return "success"
    }
}

Complete the above code addition, start Spring Boot program, access: http://localhost:8080/swagger-ui.html . You can see the page of the RESTful API shown earlier. We can then click on specific API requests, and take the POST type / api/student / request as an example, we can find the Notes information we configured in the above code and the description information of the parameter student, as shown in the following figure.


API Document Access and Debugging

On the page requested above, we see that the Example Value of the student is an input box. Yes, Swagger provides debugging and testing as well as interface functions. We can click Model Schema on the right side of the figure above (yellow area: it indicates the data structure of User). At this time, there is a template for student object in Example Value. We just need to modify it a little and click "Try it out!" Button, you can complete a request call!

At this point, we have completed the integration of Swagger2, you can test more to see whether the return results are correct, feel it is convenient to write interface documents.

Topics: Java Spring WebFlux xml