Silly silly indistinguishable synonym discrimination

When it comes to Spring automatically generating API documentation, a few words Spring to mind: Swagger, OpenAPI, Springfox… So it’s important to figure out their relationship first.

  • OpenAPI is a consortium responsible for developing standard, OpenAPI description specifications. API description files using the openAPI specification are usually compatible with a variety of related software or systems.
  • SwaggerIt started as an organization that developed the most popular API description format and donated it to the OpenAPI organization to evolve into the original OpenAPI standard. Also available are a number of peripheral tools, including famous onesswagger-ui. Was laterSmartBearCorporate acquisitions, provided againSwagger HubCommercial products.
  • Springfox is a spring-ready library that automatically generates API description files in Swagger2, Swagger3, and OpenAPI3 formats.
  • Springdoc is another spring-friendly library that generates API description files in OpenAPI3 format.

To summarize, OpenAPI is a consortium and specification, and Springfox and Springdoc are implementations of this specification. Swagger is a company that contributes a number of useful tools and helped develop the OpenAPI specification.

Why Springdoc

Obviously, Springfox hasn’t been very active lately, and it’s been two years since the release of Springfox3.x. In its defense, Springfox now supports Swagger3 and OpenAPI3 specifications as well. By contrast, the Springdoc project is very active and much more fully documented, and although only OpenAPI3 is supported, it is sufficient given that it is the latest standardized specification.

In addition, Springdoc has additional support for Spring WebFlux.

From Springfox migration

The migration process is not very technical, the official documentation is quite detailed, divided into three parts.

  1. Add Springdoc dependencies:Implementation (" org. Springdoc: springdoc openapi - UI: 1.5.9 ").
  2. Remove Springfox dependencies.
  3. Replace annotations and partial configurations. A very detailed annotation scheme is listed in the documentation.

The only thing to notice is, yes, you read that right, @ApiModel, @ApiModelProperty is replaced with @Schema. You are advised to replace @APIModelProperty (value=” XXX “) with @schema (description=” XXX “).

⚠ has a big hole for Kotlin! Remember to add the implementation(“org.springdoc: Springdoc-openapi-kotlin :1.5.9”) dependency as well as the documentation, just not in the migration guide. Otherwise, enter Swagger-UI and you will find that all attributes except one are not in effect.

Adding a Default response

In Springfox, we can add a global response structure with code like the following:

@Bean
fun createApi(a): Docket {
    val responses = listOf<Response>(
        ResponseBuilder().code("401").description("Unauthorized").build(),
        ResponseBuilder().code("403").description("Forbidden").build()
    )

    return Docket(DocumentationType.OAS_30)
        .useDefaultResponseMessages(false)
        .globalResponses(HttpMethod.GET, responses)
        .globalResponses(HttpMethod.POST, responses)
        .globalResponses(HttpMethod.DELETE, responses)
        // Other operations
        .build()
}
Copy the code

Springdoc, an upstart, is also available, and much more flexible. Because it’s more flexible, it’s a little more difficult to write:

@Bean
fun customizeOperation(a): OpenApiCustomiser {
    return OpenApiCustomiser { openApi ->
        // Get the schema for the default response code
        val schema = openApi.components.schemas[HttpErrorResp::class.java.simpleName]
        
        openApi.paths.values.forEach { pathItem ->
            pathItem.readOperations().forEach { operation ->
                // Add the default response code
                if ("401" !in operation.responses)
                    createApiResp("Unauthorized", schema)
                        .also { operation.responses.addApiResponse("401", it) }
                if ("403" !in operation.responses)
                    createApiResp("Forbidden", schema)
                        .also { operation.responses.addApiResponse("403", it) }
            }
        }
    }
}

private fun createApiResp(description: String, schema: Schema<Any>?: ApiResponse {
    val mediaType = io.swagger.v3.oas.models.media.MediaType()
        .schema(schema)
    return ApiResponse().description(description).content(
        Content().addMediaType(MediaType.APPLICATION_JSON_VALUE, mediaType)
    )
}
Copy the code

For Springdoc we need to construct an OpenApiCustomiser object that will be used to modify the resulting Api. First we read the identified schema to get the desired response body. Of course, depending on the project, you can instantiate a Schema object instead of getting a ready-made one.

Then walk through all paths and, for each, all its operations, adding default responses to each one in turn. The extra judgment is that if the response code does not exist then add it, otherwise the response defined by the API will be overwritten. This also shows the flexibility of Springdoc, where you can add arbitrary logic and make arbitrary changes to the API. Much more powerful than Springfox’s default fixed API.

Configuration items

Finally, Springdoc provides a very user-friendly set of configuration items that can be written directly into properties or YAML files. We all know that Swagger2’s default URL is… /swagger-ui.html, then Swagger3 becomes… / swagger – UI /. By default, Springdoc uses Swagger2, which makes some folks feel bad (yes, I am. So all it takes is…

springdoc:
  swagger-ui:
    path: /swagger-ui
Copy the code

Done! For more configuration items, please go to the official documentation