Skip to content
Advertisement

Swagger/Openapi – How to document imported modules in a Spring boot project?

I have an authentication module which is imported inside our projects to provide authentication related APIs.

AppConfig.java

@Configuration
@ComponentScan({"com.my.package.ldap.security"})
@EnableCaching
@EnableRetry
public class ApplicationConfig {
...
}

I’ve configured Swagger/OpenAPI in my projects and I wish to find a way to manage these imported endpoints:

enter image description here

Specifically, I wish to set an order on the Example object’s fields. Right now it is sorted alphabetically by default. The reason for doing that is because a lot of these fields are “optional” and we have to remove these fields every time from the example object in order to authenticate a user which is a waste of time.

I’ve tried annotating the Object with @JsonPropertyOrder but it makes no change:

@JsonPropertyOrder({
    "domain",
    "username",
    "password"
})

Is there any way to achieve that?

Advertisement

Answer

I made a small POC. It isn’t pretty or very extendible, but it does work as intended. Perhaps one could make it more flexible, re-using the property position on the metadata object, but this example does not include that. This way you can loop definitions and models, manually doing the work that the framework fails to do at the moment.

Also, be sure not to make this too heavy because it will be executed every time someone opens up the swagger documentation. It’s a piece of middleware that transforms the original Swagger API definition structure. It does not change the original one.

@Order(SWAGGER_PLUGIN_ORDER)
public class PropertyOrderTransformationFilter implements WebMvcSwaggerTransformationFilter {

    @Override
    public Swagger transform(final SwaggerTransformationContext<HttpServletRequest> context) {
        Swagger swagger = context.getSpecification();
        Model model = swagger.getDefinitions().get("applicationUserDetails");
        Map<String, Property> modelProperties = model.getProperties();

        // Keep a reference to the property definitions
        Property domainPropertyRef = modelProperties.get("domain");
        Property usernamePropertyRef = modelProperties.get("username");
        Property passwordPropertyRef = modelProperties.get("password");

        // Remove all entries from the underlying linkedHashMap
        modelProperties.clear();

        // Add your own keys in a specific order
        Map<String, Property> orderedPropertyMap = new LinkedHashMap<>();
        orderedPropertyMap.put("domain", domainPropertyRef);
        orderedPropertyMap.put("username", usernamePropertyRef);
        orderedPropertyMap.put("password", passwordPropertyRef);
        orderedPropertyMap.put("..rest..", otherPropertyRef);

        model.setProperties(orderedPropertyMap);
        return swagger;
    }

    @Override
    public boolean supports(final DocumentationType documentationType) {
        return SWAGGER_2.equals(documentationType);
    }
}


@Configuration
class SwaggerConf {
  @Bean
  public PropertyOrderTransformationFilter propertyOrderTransformationFilter () {
     return new PropertyOrderTransformationFilter ();
  }
}

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement