6

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.

UNOPARATOR
  • 688
  • 1
  • 6
  • 18
workharder
  • 85
  • 1
  • 6
  • Did you figure something out? Having the same problem and no luck. – ecramer Jan 16 '19 at 16:11
  • @ecramer Unfortunately, no. This should be a common problem when using swagger behind Ingress, but I cannot find any post or article mentions it. – workharder Jan 22 '19 at 16:46
  • check out this post: https://stackoverflow.com/questions/45327119/how-to-set-base-path-property-in-swagger-for-net-core-web-api. not necessarily the prettiest solution however it has worked for us – ecramer Jan 23 '19 at 16:24
  • @ecramer Indeed it works for me as well, thank you so much for letting me know. – workharder Jan 25 '19 at 22:51

4 Answers4

13

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

UNOPARATOR
  • 688
  • 1
  • 6
  • 18
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

ArlanG
  • 888
  • 9
  • 21
  • 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:/service1/swagger`, if I set the option `c.RoutePrefix = "service1";` then I can access the swagger UI by `https:/service1/service1` – workharder Oct 01 '18 at 20:22
  • It doesn't. Changing swagger access name is not what I want – workharder Oct 02 '18 at 21:22
  • 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. – ArlanG Oct 03 '18 at 14:38
0

In your ingress don't use this annotation

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