azure-func-http icon indicating copy to clipboard operation
azure-func-http copied to clipboard

swagger-ui* not loading

Open DarianAnjuhal opened this issue 3 years ago • 0 comments

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

We are currently using the same source for a local deployment (main.ts) and also an Azure deployment (main.azure.ts) Swagger is working as expected with the installed node version (node dist/src/main.js) but is not working using the installed Azure Functions Core Tools (func host start --useHttps --cors * --verbose). If is started using local azure functions files are not loaded as seen in the following image.

swagger_bug

Expected behavior

Should show the UI without problems as seen below: swagger_working

Minimal reproduction of the problem with instructions

main.azure.ts (not working)

import { NestFactory, HttpAdapterHost } from '@nestjs/core';
import { INestApplication, RequestMethod } from '@nestjs/common';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import helmet from 'helmet';
import { AllExceptionsFilter } from './base/all-exceptions.filter';
import * as databases from './config/databases';
import { BackendHandshakeDto } from './globals/dto/backend-handshake-dto';
import { VersioningType } from '@nestjs/common';

export async function createApp(): Promise<INestApplication> {
  const handshake: BackendHandshakeDto = new BackendHandshakeDto();
  const app = await NestFactory.create(AppModule);
  app.use(helmet());
  app.enableCors();
  app.use((request, response, next) => {
    response.header('Access-Control-Allow-Origin', '*');
    response.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    response.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
    next();
  });
  app.enableVersioning({
    defaultVersion: '1',
    type: VersioningType.URI,
  });

  app.setGlobalPrefix('api');

  const options = new DocumentBuilder()
    .setTitle('TUNNEL:Manager API')
    .setDescription(
      `API for TUNNEL:Manager App
      Supported database versions: ${databases.default.supportedVersions()}`,
    )
    .setVersion(handshake.backendVersion)
    .addBearerAuth()
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('api-docs', app, document, { useGlobalPrefix: true });

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(
    new AllExceptionsFilter(httpAdapter, app.get('NestWinston')),
  );

  // app.setGlobalPrefix('api', {
  //   exclude: ['swagger'],
  // });

  await app.init();
  return app;
}

main.ts (working)

import { NestFactory, HttpAdapterHost } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import helmet from 'helmet';
import * as fs from 'fs';
import { config, DotenvConfigOutput } from 'dotenv';
import { AllExceptionsFilter } from './base/all-exceptions.filter';
import * as databases from './config/databases';
import { BackendHandshakeDto } from './globals/dto/backend-handshake-dto';
import { HttpsOptions } from '@nestjs/common/interfaces/external/https-options.interface';
import { VersioningType } from '@nestjs/common';

async function bootstrap() {
  // call dotenv-config to get .env values before nest app creation
  const configuration: DotenvConfigOutput = config();
  let httpsOptions: HttpsOptions = null;
  const httpsPrivateKeyPath = configuration.parsed.HTTPS_KEY_PATH;
  const httpsCertificatePath = configuration.parsed.HTTPS_CERT_PATH;
  if (httpsPrivateKeyPath && httpsCertificatePath) {
    httpsOptions = {
      key: fs.readFileSync(httpsPrivateKeyPath),
      cert: fs.readFileSync(httpsCertificatePath),
    };
  }
  const handshake: BackendHandshakeDto = new BackendHandshakeDto();
  const app = await NestFactory.create(AppModule, { httpsOptions });
  app.use(helmet());
  app.enableCors();
  app.use((request, response, next) => {
    response.header('Access-Control-Allow-Origin', '*');
    response.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    response.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
    next();
  });
  app.enableVersioning({
    defaultVersion: '1',
    type: VersioningType.URI,
  });

  app.setGlobalPrefix('api');

  const options = new DocumentBuilder()
    .setTitle('TUNNEL:Manager API')
    .setDescription(
      `API for TUNNEL:Manager App
      Supported database versions: ${databases.default.supportedVersions()}`,
    )
    .setVersion(handshake.backendVersion)
    .addBearerAuth()
    .build();
  const document = SwaggerModule.createDocument(app, options, {
    //ignoreGlobalPrefix: false,
  });
  SwaggerModule.setup('api-docs', app, document, { useGlobalPrefix: true });

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(
    new AllExceptionsFilter(httpAdapter, app.get('NestWinston')),
  );

  await app.listen(process.env.SERVER_PORT || 3000);
}
bootstrap();

What is the motivation / use case for changing the behavior?

Environment


"dependencies": {
    "@nestjs/azure-func-http": "^0.8.0",
    "@nestjs/common": "^8.2.6",
    "@nestjs/core": "^8.2.6",
    "@nestjs/jwt": "^8.0.0",
    "@nestjs/passport": "^8.1.0",
    "@nestjs/platform-express": "^8.2.6",
    "@nestjs/swagger": "^5.2.1",
    "@nestjs/typeorm": "^8.0.3",
    "cache-manager": "^3.6.0",
    "co": "^4.6.0",
    "compare-versions": "^3.6.0",
    "helmet": "^5.0.2",
    "js-sha512": "^0.8.0",
    "markdown-it": "^12.3.2",
    "mo": "^1.7.3",
    "moment": "^2.29.1",
    "mssql": "^6.4.0",
    "nest-winston": "^1.6.2",
    "nestjs-config": "^1.4.10",
    "passport": "^0.5.2",
    "passport-jwt": "^4.0.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.5.2",
    "s": "^1.0.0",
    "swagger-ui-express": "^4.3.0",
    "typeorm": "^0.2.41",
    "winston": "^3.5.1"
  },
  "devDependencies": {
    "@azure/functions": "^1.2.3",
    "@nestjs/testing": "^8.2.6",
    "@types/express": "^4.17.13",
    "@types/jest": "^23.3.13",
    "@types/node": "12.12.43",
    "@types/readable-stream": "2.3.5",
    "@types/supertest": "^2.0.11",
    "jest": "^27.4.7",
    "nodemon": "^2.0.15",
    "prettier": "^2.5.1",
    "sqlite3": "^5.0.2",
    "supertest": "^3.4.1",
    "ts-jest": "^27.1.3",
    "ts-node": "^10.4.0",
    "tsconfig-paths": "^3.12.0",
    "tslint": "6.1.3",
    "typescript": "^4.5.5"
  },

Would be nice if somebody can help us with this issue. I guess its a weird configuration issue. Thank you anyway and bye

DarianAnjuhal avatar Apr 25 '22 15:04 DarianAnjuhal