openapi.json fails to take into account servlet context path, produces bad spec file
i have a jax-rs application, packaged in a war, deployed on tomcat with a non-empty context path (so at http://host:port/war-name). the ApplicationPath is /api
the openapi.json generated currently looks like this:
{
"openapi": "3.0.1",
"paths": {
"/api/someResourcePath": {
"get": { }
}
}
}
this produces a non-working descriptor as it fails to take into account the context path my war is deployed at. it should probably look like:
{
"openapi": "3.0.1",
"servers":[
{"url": "/war-name"}
],
"paths": {
"/api/someResourcePath": { }
}
}
@frantuma @webron - have you had a chance to look this over? is this an actual issue or did i miss a config? and if its an issue, is my fix acceptable ?
Have the same problem. I set up my REST Application with
@PostConstruct
public void init() {
System.out.println("start REST app // init");
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.prettyPrint(true)
.resourcePackages(Stream.of(this.getClass().getPackage().getName()).collect(Collectors.toSet()));
try {
openApiContext = new JaxrsOpenApiContextBuilder()
.servletConfig(servletConfig)
.application(this)
.openApiConfiguration(oasConfig)
.buildContext(true);
} catch (OpenApiConfigurationException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
but have not clue how to set the contextPath correctly.
PS if you add the server option in your basic openapi.yaml, it "works" - but I would like to change the contextPath based on my deployment name.
openAPI:
info:
version: '1.0'
title: [...]
[...]
servers:
- url: /myAppName
Prepends /myAppName to the generated URLs
I have figured this out in case anyone else has this issue.
You need to create an openapi-configuration.json file at your src/main/resources folder and load it with an openapi-configuration.json file.
https://github.com/swagger-api/swagger-core/blob/master/modules/swagger-jaxrs2/src/test/resources/integration/openapi-configuration.json
Then add servers to match the different servers for your use. Local, dev, test, prod etc. See https://swagger.io/docs/specification/api-host-and-base-path/
{
"resourcePackages": [
"com.my.project.resources",
"org.my.project.resources"
],
"openAPI": {
"servers": [ { "url":"http://localhost:8080/mypath", "description": "local server" } ],
"info": {
"version": "1.0",
"title": "Swagger Pet Sample App",
"description": "This is a TEST AAsample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"email": "[email protected]"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
}
}
}
hardcoding servers IN SOURCE CODE would probably not work in any realistic deployment system. and while listing out servers bypasses the problem i still think the auto-generation code should take deployment path into account (and i've had a patch for this for 2 years now)
in my situation this file is generated at deploy time so this isn't a problem on my end.
Generally, as mentioned in https://github.com/swagger-api/swagger-core/issues/3523#issuecomment-650571106 with reference to a similar scenario, Web app "home directory" or "base path" or "application path" can be defined in many different ways in many different environments.
The "default" way in case an @ApplicationPath is present, is to prepend it to paths. In your case or in other scenarios this might be not desired, the two easiest ways to customize this behaviour is either extending Reader or using a filter
You would for example override resolveApplicationPath() returning an empty string, or adding a filter and updating all keys of openAPI.getPaths().
Related tickets for reference:
- https://github.com/swagger-api/swagger-core/issues/3903
- https://github.com/swagger-api/swagger-core/issues/3545
- https://github.com/swagger-api/swagger-core/issues/3025
- https://github.com/swagger-api/swagger-core/issues/3523
- https://github.com/swagger-api/swagger-core/issues/3524
Closing ticket, please reopen if you're still experiencing issues
I recently fell into this problem as well, while integrating swagger-core into an updated Jakarta EE application running on JBoss EAP with JAX-RS services.
Generally, as mentioned in #3523 (comment) with reference to a similar scenario, Web app "home directory" or "base path" or "application path" can be defined in many different ways in many different environments.
I don't agree with this statement. I understand that nowadays Spring Boot and frameworks alike are more common, and probably you use an empty context path more frequently, but the concept of "context path" is standard in servlet containers and you most likely will have a non-empty context path whenever you deploy your application as a WAR or as an EAR. The presence of reverse proxies in the target picture also can introduce or change context paths, but that is also supported "out-of-the-box" by most application servers or even by Spring Boot, if proper configuration is supplied. Right now, however, the Swagger JAX-RS integration is simply "broken by default", because it does not take the context path into account. Having to customize the OpenAPI configuration just because of that sounds like a workaround to me. Especially because it's a bad idea to hardcode the context path in configuration files, so the right way to do this is to follow the programmatic approach, which increases complexity even more.
Additionally, please note that the wiki linked in the referenced comment above does not mention the "servers" configuration property at all, so finding out the right solution to this problem is not so trivial.