How to have custom context Path for Swagger Url in OpenApi3 Springboot Application
07:22 06 Jun 2022

I am migrating from springfox to OpenApi3 in my Springboot project as we have a requirement to upgrade to latest springboot with version 2.7.0

I need to configure custom contextPath for different environments like below

dev - https://qa.swagger.com/dev/api/myApp/swagger-ui/index.html

qa - https://qa.swagger.com/api/myApp/swagger-ui/index.html

uat - https://uat.swagger.com/api/myApp/swagger-ui/index.html#/

// pom.xml


        org.springframework.boot
        spring-boot-starter-parent
        2.7.0
         
    


            org.springdoc
            springdoc-openapi-ui
            1.6.8
        

        
            org.springdoc
            springdoc-openapi-webmvc-core
            1.6.8
        

// SwaggerConfig class

@Configuration
@Profile({ "local", "dev", "qat", "uat" })
public class SwaggerConfig {

@Bean
    public OpenAPI openAPI() {

        return new OpenAPI().info(info());
    }
    
    private Info info() {
         return new Info()
        .title(title)
        .version(version)
        .license(new License().name(licenseName).url(licenseUrl));
        }
}

//application.properties

spring.application.name=myApp
server.servlet.context-path=/api/${spring.application.name}

With the above configuration, I am able to run swagger using below url and getting all required response from controller apis http://localhost:8082/api/myApp/swagger-ui/index.html#/

For configuring the Swagger url for other environments,I tried to create a listener configuration class like below which didn't work

@Component
public class SwaggerListener implements ApplicationListener {

    final ApplicationPreparedEvent event = null;

    @Override
    public void onApplicationEvent(final ApplicationPreparedEvent event) {

        ConfigurableEnvironment environment = event.getApplicationContext().getEnvironment();

        Properties properties = new Properties();
        properties.put("springdoc.swagger-ui.path", swaggerPath(event));
        environment.getPropertySources().addFirst(new PropertiesPropertySource("programmatically", properties));

    }

    private String swaggerPath(final ApplicationPreparedEvent event) {
        String basePath = null;
        String swagger = "swagger-ui/index.html";
        ConfigurableEnvironment environment = event.getApplicationContext().getEnvironment();
        String[] profilesList = environment.getActiveProfiles();
        List profiles = Arrays.asList(profilesList);
        String contextPath = environment.getProperty("server.servlet.context-path");
        if (profiles != null && (profiles.contains("local"))) {
            basePath = swagger;
        } else if (profiles != null && profiles.contains("dev")) {
            basePath = "/dev/api/myApp/" + swagger;
        } else if (profiles != null && (profiles.contains("qat") || profiles.contains("uat"))) {
            basePath = "/api/myApp/";

        }
        return basePath;
    }

}

Adding above listener to main class

@SpringBootApplication(scanBasePackages = { "com.myApp.controller" })
@OpenAPIDefinition
public class myApi {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(myApi.class);
        springApplication.addListeners(new SwaggerListener());      
        springApplication.run(args);

    }

}

The above listener configuration is not working Can anyone help me out here and let me know what am I missing here ?

java spring-boot swagger springdoc-openapi-ui contextpath