Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
09546c7
Add "location-path" to swagger-ui
Dec 7, 2024
840057e
Merge branch 'main' into swagger
Mar 5, 2025
067834f
Add "location-path" to swagger-ui
Mar 5, 2025
d043978
Merge branch 'main' into swagger
alexey-plotnikoff Mar 5, 2025
8ebcae6
Code review fixes
Mar 10, 2025
c698015
Merge remote-tracking branch 'origin/swagger' into swagger
Mar 10, 2025
a6a817e
Merge branch 'main' into swagger
alexey-plotnikoff Mar 10, 2025
4005c90
Merge branch 'main' into swagger
alexey-plotnikoff Mar 11, 2025
2e3e4b5
Code review fixes
Mar 11, 2025
251bef9
Merge branch 'main' into swagger
alexey-plotnikoff Mar 11, 2025
7317647
Code review fixes
Mar 12, 2025
c87627f
Merge remote-tracking branch 'origin/swagger' into swagger
Mar 12, 2025
89cc368
fix import sort
Mar 14, 2025
4081018
Merge branch 'main' into swagger
alexey-plotnikoff Mar 14, 2025
43af23e
Merge branch 'main' into swagger
alexey-plotnikoff Mar 15, 2025
44970a3
Add "location-path" to swagger-ui
Dec 7, 2024
b7c8825
Add "location-path" to swagger-ui
Mar 5, 2025
bc6018d
Code review fixes
Mar 10, 2025
0d7353b
Code review fixes
Mar 11, 2025
c3e7ab7
fix import sort
Mar 14, 2025
b4b0af7
Merge remote-tracking branch 'origin/swagger' into swagger
Feb 16, 2026
9a1b1b1
rebase
Feb 16, 2026
6c75549
Merge branch 'main' into swagger
alexey-plotnikoff Feb 16, 2026
083be9b
fix import
Feb 16, 2026
0ff0029
Merge branch 'main' into swagger
alexey-plotnikoff Feb 16, 2026
614984c
Merge branch 'main' into swagger
alexey-plotnikoff Feb 17, 2026
ddc6831
Merge branch 'main' into swagger
alexey-plotnikoff Feb 17, 2026
5ef855b
Merge branch 'main' into swagger
alexey-plotnikoff Mar 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,10 @@ public class SwaggerUiConfig {
*/
@ConfigItem(defaultValue = "false")
boolean tryItOutEnabled;

/**
* If application behind the proxy with custom location path.
*/
@ConfigItem
Optional<String> locationPath;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the root path for openapi?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2025-03-05 at 22 38 32

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should rename locationPath to rootPath?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ public void getSwaggerUiFinalDestination(
}

String openApiPath = nonApplicationRootPathBuildItem.resolvePath(openapi.path);
if (swaggerUiConfig.locationPath.isPresent()) {
openApiPath = swaggerUiConfig.locationPath.get() + openApiPath;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may have to normalized the resulting path, or do we expect it to be consistent?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean I should check a forward slash at the start of swaggerUiConfig.locationPath.get() if it doesn't exists?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, also that the given URL is normalized: https://en.wikipedia.org/wiki/URI_normalization

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

String swaggerUiPath = nonApplicationRootPathBuildItem.resolvePath(swaggerUiConfig.path);
ThemeHref theme = swaggerUiConfig.theme.orElse(ThemeHref.feeling_blue);
Expand Down Expand Up @@ -379,6 +382,12 @@ private byte[] generateIndexHtml(String openApiPath, String swaggerUiPath, Swagg
if (swaggerUiConfig.queryConfigEnabled) {
options.put(Option.queryConfigEnabled, "true");
}
if (swaggerUiConfig.locationPath.isPresent()) {
var locationPath = swaggerUiConfig.locationPath.get();
addLocationPath(locationPath, Option.selfHref, options);
addLocationPath(locationPath, Option.backHref, options);
addLocationPath(locationPath, Option.oauth2RedirectUrl, options);
}
Comment on lines +421 to +426
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My problem with how it's implemented is that the value is fixed at build time.

Will it fly in standard setups? (Honest question, I don't have an answer)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question.

@phillip-kruger what do you think?

Copy link
Author

@alexey-plotnikoff alexey-plotnikoff Mar 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @gsmet but we have same problem for all variables in indexHtmlContent:

  1. openApiPath = nonApplicationRootPathBuildItem.resolvePath(openapi.path());
  2. swaggerUiPath
  3. swaggerUiConfig
  4. launchMode
  5. devServicesLauncherConfigResultBuildItem

Maybe we should fix this in another PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point swagger ui html is generated at build time. allowing dynamic creation at runtime will be a big change. We can maybe change the static generated html and js to allow some parameters that can change behavior at runtime, but even that is a much bigger change


ObjectMapper objectMapper = new ObjectMapper();
Map<String, String> oauthAdditionalQueryStringParamMap = new HashMap<>();
Expand Down Expand Up @@ -437,6 +446,13 @@ private byte[] generateIndexHtml(String openApiPath, String swaggerUiPath, Swagg
return IndexHtmlCreator.createIndexHtml(urlsMap, swaggerUiConfig.urlsPrimaryName.orElse(null), options);
}

private void addLocationPath(String locationPath, Option key, Map<Option, String> options) {
var value = options.get(key);
if (value != null) {
options.put(key, locationPath + value);
}
}

private static boolean shouldInclude(LaunchModeBuildItem launchMode, SwaggerUiConfig swaggerUiConfig) {
return launchMode.getLaunchMode().isDevOrTest() || swaggerUiConfig.alwaysInclude;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.quarkus.swaggerui.deployment;

import static org.hamcrest.Matchers.containsString;

import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

public class LocationPathTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addAsResource(new StringAsset(
"quarkus.swagger-ui.location-path=/nginx/path"), "application.properties"));

@Test
public void shouldUseCustomOpenApiPath() {
RestAssured.when().get("/q/swagger-ui").then().statusCode(200).body(containsString("/nginx/path/q/openapi"));
RestAssured.when().get("/q/swagger-ui/index.html").then().statusCode(200).body(containsString("/nginx/path/q/openapi"));
RestAssured.when().get("/q/swagger-ui").then()
.statusCode(200)
.body(containsString("/nginx/path/q/swagger-ui/oauth2-redirect.html"));
RestAssured.when().get("/q/swagger-ui/index.html").then()
.statusCode(200)
.body(containsString("/nginx/path/q/swagger-ui/oauth2-redirect.html"));
RestAssured.when().get("/q/swagger-ui").then()
.statusCode(200)
.body(containsString("/nginx/path/q/dev"));
RestAssured.when().get("/q/swagger-ui/index.html").then()
.statusCode(200)
.body(containsString("/nginx/path/q/dev"));
RestAssured.when().get("/q/swagger-ui").then()
.statusCode(200)
.body(containsString("/nginx/path/q/swagger-ui"));
RestAssured.when().get("/q/swagger-ui/index.html").then()
.statusCode(200)
.body(containsString("/nginx/path/q/swagger-ui"));
}
}