Swagger: change api route in Swagger UI
Asked Answered
R

5

7

I have two kubernetes services deployed on a AKS, they receive traffic from a Nginx Ingress Controller. The endpoints for these two services are https:<dns>/service1and https:<dns>/service2. Now I want to set up Swagger for each services. Below is how I set up Swagger UI for one of the services.

app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/service1/swagger/v1/swagger.json", "API V1");
        });

With this configuration, I can get access to swagger by https:<dns>/service1/swagger.

Now the problem is, in Swagger UI, when I want to test the api by clicking the "Try it out" button then Excute button, the url that Swagger UI access is https:<dns>/api/v1/contoller instead of https:<dns>/service1/api/v1/contoller. Which means that Swagger UI is not aware of the existance of path /service1/. I found several related questions like this one How to change base url of Swagger in ASP.NET core . But they are not the solution for my problem. My guess is I need to set a base path for Swagger. If anyone could tell me how to configure base path for Swagger in ASP.NET core 2.0, it would be much appreciated.

Rosebud answered 13/9, 2018 at 16:12 Comment(4)
Did you figure something out? Having the same problem and no luck.Gateway
@Gateway Unfortunately, no. This should be a common problem when using swagger behind Ingress, but I cannot find any post or article mentions it.Rosebud
check out this post: #45327619. not necessarily the prettiest solution however it has worked for usGateway
@Gateway Indeed it works for me as well, thank you so much for letting me know.Rosebud
S
15

Change this:

app.UseSwagger();
app.UseSwaggerUI(c =>
{
  c.SwaggerEndpoint("/service1/swagger/v1/swagger.json", "API V1");
});

to this:

For dotnet core 2.x

app.UseSwagger(c =>
{
#if !DEBUG
  c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.BasePath = "/service1");
#endif
});
app.UseSwaggerUI(c =>
{
  c.SwaggerEndpoint("./swagger/v1/swagger.json", "API V1");
});

For dotnet core 3.x (Swashbuckle 5.x prerelease+)

app.UseSwagger(c =>
{
#if !DEBUG
  c.RouteTemplate = "swagger/{documentName}/swagger.json";
  c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.Servers = new System.Collections.Generic.List<OpenApiServer>
  {
    new OpenApiServer { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}/service1" }
  });
#endif
});
app.UseSwaggerUI(c =>
{
  c.SwaggerEndpoint("./swagger/v1/swagger.json", "API V1");
});

#if !DEBUG ... #endif is necessary for accessing the swagger ui while debugging in local machine.

Note: I'm assuming "/service1" is the same value as in your values.yaml file of your helm chart. (see below)

...
ingress:
  enabled: true
  annotations: {
    kubernetes.io/ingress.class: "nginx",
    nginx.ingress.kubernetes.io/rewrite-target: /$1
  }
  path: /service1/?(.*)
  hosts:
    - your-aks-subdomain.your-azure-region.cloudapp.azure.com
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

hpa:
...

Snowmobile answered 4/10, 2019 at 11:53 Comment(0)
P
1

Please en your public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {

use after this:

app.UseSwaggerUI(c=>
              {
                   c.SwaggerEndpoint("/service1/swagger/v1/swagger.json", "Giftaway API V1");

This option

c.RoutePrefix = "service1";

this will get you https:<dns>/service1/api/v1/controller

Prang answered 1/10, 2018 at 16:13 Comment(5)
Thank you for your reply. The "RoutePrefix" option is actually used to change swagger endpoint. In my case, if it is not set, the swagger UI can be accessed by https:<dns>/service1/swagger, if I set the option c.RoutePrefix = "service1"; then I can access the swagger UI by https:<dns>/service1/service1Rosebud
It doesn't. Changing swagger access name is not what I wantRosebud
When you mean that tha url changes to service1/service1 you mean when you are accessing to swagger.json? If this is the case you need to change c.SwaggerEndpoint("/service1/swagger/v1/swagger.json", "Giftaway API V1"); to c.SwaggerEndpoint("/swagger/v1/swagger.json", "Giftaway API V1");. You need to specify only the base route on c.RoutePrefix = "service1"; and this route will work for every enpoint. In case you need it in service url, you need to add it on Route("api/{Controller}")] in your controllers or use sa middleware to add the path to the base route.Prang
Thanks! Your .NET core 3 example works in .NET 6, Swashbuckle 6.5, OpenApi 3, but I removed the c.RouteTemplate line because that is the same as the default value now.Rampageous
Good, please provide the example as an update fro this issue! Thank you!Prang
R
0

In your ingress don't use this annotation

nginx.ingress.kubernetes.io/rewrite-target: /

Revivalist answered 9/11, 2018 at 11:7 Comment(0)
B
0

I am using ASP.NET Core 6 with Swashbuckle.AspNetCore 6.5 and UNOPARATOR required changes for it to work:

        app.UseSwagger(c =>
        {
#if !DEBUG

            c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.Servers = new List<OpenApiServer>
            {
                // {httpReq.Scheme} is http on deployed version, so hardcoding https
                new OpenApiServer { Url = $"https://{httpReq.Host.Value}/serviceName" }
            });
#endif
        });
        app.UseSwaggerUI();

What I do not understand is why httpReq.Scheme returned http when deployed, but I have https everywhere, so I can safely hardcoded (not happy with this though).

Beezer answered 30/10, 2023 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.