fastify / fastify-swagger-ui

Serve Swagger-UI for Fastify
MIT License
132 stars 40 forks source link

The Swagger UI is failing to display any content on the Amazon EC2 instance. #74

Closed hanancs closed 2 weeks ago

hanancs commented 1 year ago

Prerequisites

Fastify version

4.0.0

Plugin version

1.8.0

Node.js version

18.15.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.3.1 (a)

Description

A Node.js application utilizing the Fastify framework, and api is documented using "fastify-swagger" and "fastify-swagger-ui". The Swagger UI loads seamlessly on my local server at "localhost:3000/v1/docs" and operates without any issues.

However, when I deployed the application to an Amazon EC2 instance (running on Amazon Linux), I encountered a problem. Although all APIs function correctly on the server, navigating to "myamazonurl.com/docs/static/index.html" redirects me to the Swagger UI, which, unfortunately, does not display anything.

The console and network are both displaying errors that seem identical.

Steps to Reproduce

I have attached these errors for further clarification.

image

Expected Behavior

Swagger UI should be accessible and displayed correctly on the EC2 instance, and the server itself should not force itself to find resources(Swagger resources) on the HTTPS scheme.

image
mcollina commented 1 year ago

Thanks for reporting!

Unfortunately, the steps you are providing are far from being useful to diagnose and debug this. We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

jsumners commented 1 year ago

Sounds similar to https://github.com/fastify/fastify-swagger/issues/397

maioranoknobs commented 11 months ago

Does anyone have a solution to this problem? I'm having the same problem with swagger ui, locally it works correctly but when I deploy on AWS Cloudformation (i'm using fastify lambda) I get the 504 Gateway Timeout error. This is my own configuration:

const registerSwaggerPlugin = async (server: FastifyInstance) => {

  server.register(swagger, {
    swagger: {
      info: {
        title: "Backend swagger",
        description: "Swagger for Backend API",
        version: "0.1.0",
      },
      externalDocs: {
        url: "https://swagger.io",
        description: "Find more swagger info here",
      },
      host: "localhost:3000",
      schemes: ["http"],
      consumes: ["application/json"],
      produces: ["application/json"],
      securityDefinitions: {
        apiKey: {
          type: "apiKey",
          name: "apiKey",
          in: "header",
        },
      },
    },
  });

  server.register(swaggerUi, {
    routePrefix: '/docs',
    uiConfig: {
      docExpansion: 'list',
      deepLinking: false
    },
    uiHooks: {
      onRequest: function (request, reply, next) { next() },
      preHandler: function (request, reply, next) { next() }
    },
    staticCSP: true,
    transformStaticCSP: (header) => header,
    transformSpecification: (swaggerObject, request, reply) => { return swaggerObject },
    transformSpecificationClone: true
  });

}
jnixon2 commented 11 months ago

I also seem to be getting the same issue with AWS lambda, works fine locally but then when coming through lambda and Apigateway I get a blank page.

maioranoknobs commented 11 months ago

In my case I solved the problem by increasing the API_TIMEOUT parameter. I set a generic timeout on my API so that they would respond with a 504 in case the server did not respond within a certain time, i think that due to the cold start of the lambda function the call to the /docs/static/index.html page took longer than the API_TIMEOUT and therefore didn't render the page correctly, I hope it helps

const setAppTimeout = async (server: FastifyInstance) => {

  await server.addHook('onRequest', (request, response, done) => {
    const timeoutMs = parseInt(process.env.API_TIMEOUT!, 10);
    // Check if the response has already been sent
    if (response.sent) {
      done();
      return;
    }
    setTimeout(() => {
      // Check again if the response was already sent before sending it again
      if (!response.sent) {
        httpResponse.handleTimeoutServerError(response, "Timeout error: The request took too long to process.");
      }
    }, timeoutMs);
    done();
  });

}
davidjbng commented 9 months ago

I have attached these errors for further clarification.

image

Expected Behavior

Swagger UI should be accessible and displayed correctly on the EC2 instance, and the server itself should not force itself to find resources(Swagger resources) on the HTTPS scheme.

image

Can you confirm that the static assets are available on your server? Do you bundle your api? Looks similar to #65 to me.

phabreeze commented 3 weeks ago

Having the exact same issue when running behind Azure API Management. It looks like all subdirectories in between the domain and /documentation/ are being removed, e.g. https://something.com/my-api/documentation redirects to https://something.com/documentation

climba03003 commented 3 weeks ago

Having the exact same issue when running behind Azure API Management. It looks like all subdirectories in between the domain and /documentation/ are being removed, e.g. https://something.com/my-api/documentation redirects to https://something.com/documentation

Please try 4.1.0 version for your case.

hanancs commented 2 weeks ago

The issue is not related to the EC2 instance but to the absence of SSL (HTTPS) on your DNS configuration. Swagger UI requires SSL when accessed over a live domain. It works on localhost without SSL, but in a live environment, Swagger UI must be accessed via HTTPS.

To resolve this, configure SSL for your domain to ensure the Swagger UI loads correctly in production.