To allow us some simple, fast and accessible debugging and smoke testing of our services, we use the Swagger Web UI with the "Try it out" function.
This works well for local development and gives fast feedback.
These services are deployed in Kubernetes and each service we create and deploy is accessible via its own subpath on the main domain of the application, e.g.:
https://app.example.org/book-import/swagger/...
https://app.example.org/order-export/swagger/...
...
The Swagger UI is accessible via https://app.example.org/book-import/swagger/index.html
but the URLs generated in the UI still assume "no sub path" and the URLs for the "Try it out" requests look like this: https://app.example.org/api/...
instead of https://app.example.org/book-import/api/...
I tried to use the PreSerializeFilters
but it behaves not as expected.
This is what I have currently:
app.MapSwaggerDefaults(builder.Configuration, swaggerOptions: options =>
{
options.PreSerializeFilters.Add((swagger, httpReq) =>
{
app.Services.GetRequiredService<ILogger<Program>>().LogInformation("Swagger path: {Path}", httpReq.Path.Value);
if (httpReq.Path.Value != null && !httpReq.Path.Value.StartsWith("/swagger"))
{
swagger.Servers = new List<OpenApiServer> { new OpenApiServer { Url = httpReq.Path.Value.Replace("/swagger", "!").Split('!')[0] } };
}
});
});
I am trying to replace the /swagger
part with the whole request URL if it’s not starting with /swagger
.
Running this version of the app locally in Visual Studio "works", because I can set a break point in the if (httpReq.Path.Value != ...
and it breaks there. But if I run this same code via the Visual Studio Kubernetes Bridge on a fully deployed cluster or build and push a new image containing this change and deploying it to the fully deployed cluster, it does not work.
The URLs are not changed in the Swagger UI and I dont even see the log output Swagger path:
How can i set the URLs for the "Try it out" feature of the Swagger UI, so that it works when the app is running in a sub path?
Or do these PreSerializeFilters
work differently on K8s?
What I also tried, without success:
builder.Services.AddSwaggerGen(o =>
o.SwaggerGeneratorOptions.Servers = new List<OpenApiServer> { new OpenApiServer { Url = "/book-import" }
});
.NET 8
Swashbuckle.AspNetCore 6.8.1
2
Answers
After trying numerous options and ways to rewrite the URL in the "Try it out" tab, I have now written a Pre-Serializer-Filter which reads the X-Forwarded Headers and rebuilds the Swagger Server URL if needed:
I assume that your .net app has a reverse proxy in front of it that allows you to you to proxy each sub path to your different applications ?
I can see two ways you can sort this problem :
P.S. the reason you don’t see the logs is the reverse proxy in your k8s is eating the request and not feeding them to your app.