workharder
workharder

Reputation: 95

Swagger: change api route in Swagger UI

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.

Upvotes: 7

Views: 10475

Answers (5)

Alexei - check Codidact
Alexei - check Codidact

Reputation: 23098

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).

Upvotes: 0

UNOPARATOR
UNOPARATOR

Reputation: 706

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:
...

Upvotes: 15

Kapil Ghimire
Kapil Ghimire

Reputation: 101

In your ingress don't use this annotation

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

Upvotes: 0

ArlanG
ArlanG

Reputation: 1036

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

Upvotes: 1

Related Questions