Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swagger UI not working as expected while service behind Nginx reverse-proxy

Tags:

nginx

swagger

I use swagger-ui-express package(https://github.com/scottie1984/swagger-ui-express) (Node.js) and work fine with this config:

const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
app.use('/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerDocument));

when directly got to /api-docs every thing is fine, but when i come from nginx for example host/myApp/api-docs redirect me to host/api-docs and it's obvious that after redirect I get 404

like image 832
Mohammad Ranjbar Z Avatar asked Sep 17 '19 06:09

Mohammad Ranjbar Z


4 Answers

The problem was for the swagger-ui-express middleware that redirect user to host/api-docs and don't use the prefix of path, so I solved this problem with a trick I use middleware with this path :

const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
app.use('/app-prefix/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerDocument));

and in nginx I defined two location :



  location /app-prefix/api-docs {
      proxy_pass http://172.18.0.89:3000/app-prefix/api-docs;
  }

  location /app-prefix/ {
      proxy_pass http://172.18.0.89:3000/;
  }


so when user request to nginx , nginx route it to application second path : /app-prefix/api-docs

and after that swagger middlware redirect it to host/app-prefix/api-docs and redirect to correct path, now application route and swagger works fine.

like image 171
Mohammad Ranjbar Z Avatar answered Nov 17 '22 04:11

Mohammad Ranjbar Z


add this options and test it :

    explorer: true,
    swaggerOptions: {
        validatorUrl: null
    }
};
app.use('/api-docs',swaggerUi.serve, swaggerUi.setup(swaggerDocument, swaggerOption));```
like image 29
fateme ghasemi Avatar answered Nov 17 '22 05:11

fateme ghasemi


This is an old question, but I just run into the same problem. I am able to resolve this without using ngnix rewrite.

// serve the swagger ui in a temporary directory
app.use('/temp-api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

// swagger-ui-express middleware that redirect user to /api-docs will not be aware the prefix of path by ngnix
const apiDocsRedirectPath = "application/prefix/go/here".concat('/temp-api-docs/');
app.get('/api-docs', function(req, res) {
    res.redirect(apiDocsRedirectPath);
});
like image 2
user2785473 Avatar answered Nov 17 '22 04:11

user2785473


I also had this problem and the marked correct answer worked for me. However, I do not understand how it is working because I don't know much about Nginx.

Here is my solution for future people with this issue.

this.app.use(
    "/api-docs",
    swaggerUi.serve,
    swaggerUi.setup(openapiSpecification as OpenAPIV3.Document)
);

The express app itself is behind an nginx proxy which looks like this

location /api/v1/myapp/ {
    proxy_pass http://myapp:3001/;
}

So when a request is made to example.com/api/v1/myapp/api-docs it comes out of the proxy to myapp like myapp:3001/api-docs which is fine, up until (I think) swagger UI express tries to load resources from example.com/api-docs which will 404 of course.

I solved it by adding this as a redirect.

location /api/v1/myapp/ {
    proxy_pass http://myapp:3001/;
}

location /api-docs/ {
    return 302 /api/v1/myapp/api-docs/;
}

So now when swagger goes off to request things at example.com/api-docs it is redirected to the correct location block and works like normal.

Again, not an expert with this but this seems to work and I think its easy to understand.

The caveat is that you are stuck with just one /api-docs so if you have multiple swagger endpoints this does not work.

like image 2
Roland Warburton Avatar answered Nov 17 '22 04:11

Roland Warburton