Reputation: 1298
I'm running a service, where Swagger UI is accessible at:
http://serviceURL/swagger-ui.html
However, it is behind a proxy, such as:
http://proxyURL/serviceName
Generated URLs by Swagger UI are looking like:
http://proxyURL/
instead of the actual URL with the serviceName as suffix. As far as I get it, this means manipulating the basePath property. As per documentation:
A swagger API documentation can no longer describe operations on different base paths. In 1.2 and earlier, each resource could have had a separate basePath. In 2.0, the basePath equivalents (schemes+host+basePath) are defined for the whole specification.
@Api(basePath) is deprecated, and it doesn't say what to use and how to use it. How to make the paths generated by Swagger appear properly?
I'm using Spring Boot, Springfox Swagger and annotations.
Upvotes: 35
Views: 29199
Reputation: 27
I added the following config into my application.yaml file:
springdoc:
swagger-ui:
configUrl: /pathProvider/v3/api-docs/swagger-config
disable-swagger-default-url: true
urls[0]:
url: /pathProvider/v3/api-docs/mobile-bff
name: pathName
where pathProvider should be replaced by the PathProvider config in the old swagger 2 yaml...
and also, had do add a server into the OpenAPI object with the same PathProvider name.
@Bean fun springShopOpenAPI(): OpenAPI? { return OpenAPI().addServersItem(Server().url("/pathProvider"))
Upvotes: -1
Reputation: 41
Using spring fox 2.9.2, using solution mentioned by other users is not works.
What is not working:
I don't know why they are not work, but in my project that using Springboot 2.1.6.RELEASE and Spring 5.1.8.RELEASE, the two solution above is being ignored.
So, I am trying another approach: https://github.com/springfox/springfox/issues/2817#issuecomment-517753110
According to the github issue comment, I need to override Springfox json serialize class and thank god this works. Here is the code example:
import io.swagger.models.Swagger;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import springfox.documentation.spring.web.json.JacksonModuleRegistrar;
import springfox.documentation.spring.web.json.Json;
import springfox.documentation.spring.web.json.JsonSerializer;
import java.util.Arrays;
import java.util.List;
import static io.github.jhipster.config.JHipsterConstants.SPRING_PROFILE_PRODUCTION;
@Component
@Primary
public class CustomBasePathSerialize extends JsonSerializer {
// this injection is optional, if you don't need to
// add basePath based on active profile, remove this.
private final Environment env;
public CustomBasePathSerialize(List<JacksonModuleRegistrar> modules,
Environment env) {
super(modules);
this.env = env;
}
@Override
public Json toJson(Object toSerialize) {
if (toSerialize instanceof Swagger) {
Swagger swagger = (Swagger) toSerialize;
String basePath = "/serviceName";
List<String> profiles = Arrays.asList(env.getActiveProfiles());
// OPTIONAL: you can change basePath if you have difference path
// on any Spring profile, for example prod:
if (profiles.contains(SPRING_PROFILE_PRODUCTION)) {
basePath = "/";
}
swagger.basePath(basePath);
}
return super.toJson(toSerialize);
}
}
Upvotes: 4
Reputation: 22292
Take care to replace the
package
(which need to be the one containing your REST controllers), thehost
, and thePATH
you need
@Configuration
@EnableSwagger2
public class SwaggerConfiguration implements WebMvcConfigurer {
public static final String PATH = "/serviceName";
@Bean
public Docket api() {
final var package = "com.martin.rest";
final var host = "localhost:8080";
return new Docket(DocumentationType.SWAGGER_2)
.host(host)
.select()
.apis(RequestHandlerSelectors.basePackage(package))
.paths(PathSelectors.any())
.build();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
final var apiDocs = "/v2/api-docs";
final var configUi = "/swagger-resources/configuration/ui";
final var configSecurity = "/swagger-resources/configuration/security";
final var resources = "/swagger-resources";
registry.addRedirectViewController(PATH + apiDocs, apiDocs).setKeepQueryParams(true);
registry.addRedirectViewController(PATH + resources, resources);
registry.addRedirectViewController(PATH + configUi, configUi);
registry.addRedirectViewController(PATH + configSecurity, configSecurity);
registry.addRedirectViewController(PATH, "/");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(PATH + "/**").addResourceLocations("classpath:/META-INF/resources/");
}
}
Edit pour application.properties
file:
server.servlet.context-path=/serviceName
Or if you have an application.yml
file:
server:
servlet:
context-path: /serviceName
Warning: It will change the base path of all your web services, not only Swagger
Upvotes: 4
Reputation: 476
@Bean
public Docket newsApi(ServletContext servletContext) {
return new Docket(DocumentationType.SWAGGER_2).pathProvider(new RelativePathProvider(servletContext) {
@Override
public String getApplicationBasePath() {
return "/serviceName" + super.getApplicationBasePath();
}
}).host("proxyURL");
}
Upvotes: 16