Introduction on pit

Swagger3.0 has been out for some time, although it simplifies the basic configuration, but as a big version of the upgrade there are certainly many problems, many 2.x version of the class are marked as obsolete, most of the class construction and attribute Settings are still assigned to the corresponding Buidler, but many configurations are introduced to handle the functional interface. This can be difficult to configure for developers who are not familiar with functional programming. At present, there are few configuration introduction of 3.0 version in China, so AFTER upgrading Swagger to 3.0, I checked the source code that replaced the corresponding function of marking obsolescent (@deprecated) and configured it accordingly. As a result, I stepped on two pits, so I share the record of stepping down pits and the general configuration mode of 3.0.

Record on pit

JWT authentication is used in the project, but it is very troublesome for both developers and testers to log in to obtain token before Swagger interface testing every time. So I decided to set the Authorization to global header and set the default value according to the global parameter Settings commonly used for Swagger, so I have the following configuration in 3.0(OAS_30 refers to Open API Spefication 3.0) :

@Bean public Docket docket() { return new Docket(DocumentationType.OAS_30) .globalRequestParameters(Lists.newArrayList( new RequestParameterBuilder() .name("debug") .description("ignore authorization") .in(ParameterType.HEADER) // Class to create a default builder for attribute set. The query (parameterSpecificationBuilder - > parameterSpecificationBuilder. DefaultValue (" 1 ") .allowEmptyValue(true)) .build(), new RequestParameterBuilder() .name("Authorization") .description("token") .query(parameterSpecificationBuilder -> parameterSpecificationBuilder.defaultValue("1") .allowEmptyValue(true)) .in(ParameterType.HEADER) .build() )) .select() .paths(PathSelectors.regex("^(?! /error).*")) .build(); }Copy the code

Query () in the above configuration can be regarded as a core of the configuration style in Swagger3.0: Create the corresponding property object Builder in the configuration class, and expose a method of the Conumser function interface of the Builder as a parameter. The developer provides a Consumer to operate on the Builder as required (property setting). As long as you understand the style I believe that basically the new version of the configuration look at the source code can quickly get started. RequestParameterBuilder = simpleParameterBuilder = simpleParameterBuilder = simpleParameterBuilder = simpleParameterBuilder

public class RequestParameterBuilder { ...... SimpleParameterSpecificationBuilder simpleParameterBuilder; . private SimpleParameterSpecificationBuilder queryBuilder() { if (simpleParameterBuilder == null) { simpleParameterBuilder = new SimpleParameterSpecificationBuilder(); } return simpleParameterBuilder; } public RequestParameterBuilder query(@NonNull Consumer<SimpleParameterSpecificationBuilder> parameter) { parameter.accept(queryBuilder()); return this; }...Copy the code

In fact, I think since the integration of SpringBoot will be more convenient for developers to use the properties class as the leading property setting instead of Builder and FunctionalInterface, now I will step on the pit fill pit. According to the 2.x version configuration and understanding, I thought there should be no problem with the above configuration, but there were 2 pits.

Pit A: Name isAuthorizationThe global header parameter value will not be passed to the back end

When I add oneAuthorizationWhen testing the global header, I found that it was not transmitted to the back end. At first, I thought it was a bug of Swagger, but considering the sensitivity of this name, I checked OpenAPI 3.0(Swagger 3.0 is based onOpenAPI 3.0 specificationThe data format of the document also follows the 3.0 specification), so I found the following content:When the global header argument contains a name namedAccpet,Content-Type,AuthorizationThe definition of the parameter is ignored. So I added a non-ignored header and got the following result:

You can see that debug is received in the global header setting, while Authorization is ignored, which basically confirms that it is not a bug, but I did not read the specification. The Authorization header defined in this way will not be accepted, but previous versions of Swagger also have a way to set the global token. SecurityContext and SecurityReference

@Bean public Docket docket() { return new Docket(DocumentationType.OAS_30) .securityContexts(Arrays.asList(SecurityContext.builder() .securityReferences(Arrays.asList(SecurityReference.builder() .reference("Authorization") .scopes(new AuthorizationScope[]{new AuthorizationScope("global", "accessEverything")}) .build())) .build())) .securitySchemes(Arrays.asList(new ApiKey("Authorization", "Authorization", "header"))) .select() .paths(PathSelectors.regex("^(? ! /error).*")) .build(); }Copy the code

SecurityContextwithSecurityReferenceThe Settings are little changed from previous versions, and the results are as personal as expected (available on the back end)AuthorizationHeader), but the default value cannot be set for the header configured in this way. The effect picture is as follows:

Pit B: Default values for global parameters are not in effect

Although throughquery()Method sets the parameter default value, but essentially Swagger does not set that default value to the page, as you can see from the demo figure 1 in pit 1 even though the global parameter is set to its initial value1“But the page is still empty. This pit was confirmed to be a 3.0 bug, which was also found on GithubissueThis bug has been added to the 3.0.1 milestone (it will be fixed in 3.0.1) :

conclusion

Although the use of official frameworks is more common, it is still feltI wrote it myself, if the above 3.0 version of the problem will affect the current project test use, it is not recommended to upgrade, play ok.