Search code examples
springspring-bootswaggerspringfox

How set SpringFox to show two (or more) versions of the Rest API using Spring Boot?


I'm trying to figure out how manage two (or more) version of my API endpoints using Spring Fox.

To version my APIs, I'm using the Versioning through content negotiation, also know as Versioning using Accept header. The versions of each endpoint are controlled individually using the header information. Per example, for the version one I use the attribute produces:

@Override
@PostMapping(
        produces = "application/vnd.company.v1+json")
public ResponseEntity<User> createUser(

For version two, I use:

@Override
@PostMapping(
        produces = "application/vnd.company.v2+json",
        consumes = "application/vnd.company.v2+json")
public ResponseEntity<User> createUserVersion2(

I not use consumes for the first (v1) version, so if the client use only application/json on the call the first version will be called by default.

I would like to show the two version on the Swagger UI. How to do that?


Solution

  • It's very simple. Just create one Docket for each version.

    Example, the first version:

    @Bean
    public Docket customImplementation(
            @Value("${springfox.documentation.info.title}") String title,
            @Value("${springfox.documentation.info.description}") String description) {
    
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo(title, description, "1.0"))
                .groupName("v1")
                .useDefaultResponseMessages(false)
                .securitySchemes(newArrayList(apiKey()))
                .pathMapping("/api")
                .securityContexts(newArrayList(securityContext())).select()
                .apis(e -> Objects.requireNonNull(e).produces().parallelStream()
                        .anyMatch(p -> "application/vnd.company.v1+json".equals(p.toString())))
                .paths(PathSelectors.any())
                .build();
    }
    

    And for version two:

    @Bean
    public Docket customImplementationV2(
            @Value("${springfox.documentation.info.title}") String title,
            @Value("${springfox.documentation.info.description}") String description) {
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo(title, description, "2.0"))
                    .groupName("v2")
                    .select()
                    .apis(e -> Objects.requireNonNull(e).produces()
                            .parallelStream()
                            .anyMatch(p -> "application/vnd.company.v2+json".equals(p.toString())))
                    .build();
    }
    

    The secret here is filter the available endpoints by the produces attribute.

    The Swagger-UI will show the two versions on the combo:

    enter image description here

    This code needs to be on a class annotated with @Configuration. You also need to enable the Swagger with @EnableSwagger2.