[ ] 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.
Swagger endpoint is not found.
Html response generated by swagger-ui.
Here is an example I use in my project.
I'd like to generate swagger documents based on my modules and endpoints, but I cannot.
"@nestjs/common": "^5.4.0",
"@nestjs/core": "^5.4.0",
"@nestjs/swagger": "^2.5.1",
"aws-serverless-express": "^3.3.5",
"express": "^4.16.4",
For Tooling issues:
- Node version: 8.10
- Platform: Mac
Others:
I run my environment with serverless and serverless-offline plugin
@csakbalint I just ran into this the other day. The problem is that given a swagger path of swagger, swagger-ui-express serves its html file from /swagger/ and will redirect if the request path is /swagger. Unfortunately API Gateway strips the trailing slash from the request path so you have to add it back with the block below.
if (event.path === '/swagger') {
event.path = '/swagger/';
}
This cannot be done as a middleware as req.path from express is a getter and will throw an error if you try to overwrite it.
I have the similar problem. Swagger documentation doesn't work on AWS lambda using serverless framework. It works testing it locally (sls offline start).
What is very strange, that only one file .js and doesn't have 404. Others does. I have no idea why.
Swagger API documentation:
https://js6bdk1qg3.execute-api.eu-west-2.amazonaws.com/master/api
404:
https://js6bdk1qg3.execute-api.eu-west-2.amazonaws.com/master/swagger-ui-bundle.js
200:
https://js6bdk1qg3.execute-api.eu-west-2.amazonaws.com/master/swagger-ui-init.js
My part of configuration:
if (event.path === '/api') {
event.path = '/api/';
}
event.path = event.path.includes('swagger-ui') ? `/api${event.path}` : event.path;
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
export default (app, isServerless = false): void => {
const serverUrl = isServerless ? '/dev' : '/';
const options = new DocumentBuilder()
.setTitle(process.env.APP_NAME)
.setDescription(process.env.APP_DESC)
.setVersion('1.0')
.addServer(serverUrl)
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('api', app, document);
};
@jtmthf @csakbalint would you have any idea?
Hi @plorencrstit , I am trying to use swagger with serverless and lambda functions.
Can you explain how did you configure it ?
Hi @NastyZ98,
what problem do you have?
Using TS and serverless-plugin-optimize plugin I needed to add to my serverless.yml configuration:
custom:
optimize:
external: ['swagger-ui-dist']
in lambda.ts: [my handler]
export const handler: Handler = async (event: any, context: Context) => {
if (event.path === '/api') {
event.path = '/api/';
}
event.path = event.path.includes('swagger-ui') ? `/api${event.path}` : event.path;
cachedServer = await bootstrapServer();
return proxy(cachedServer, event, context, 'PROMISE').promise;
};
@plorencrstit hi, thank you for your reply,
I am trying to make swagger working on my aws lambda but it result of a 404 with sls offline and of an error 500 when I deploy on aws.
I also added serverless-plugin-optimize and edited my serverless.yml but it looks like that serverless-plugin-optimize broke something when I call: myawsurl/dev/api

Here is my lambda.ts
const binaryMimeTypes: string[] = [];
let cachedServer: Server;
process.on('unhandledRejection', reason => {
console.error(reason);
});
process.on('uncaughtException', reason => {
console.error(reason);
});
function setupSwagger(app: INestApplication) {
const options = new DocumentBuilder()
.setTitle('Tyffis API')
.setDescription('Tyffis REST API documentation')
.setVersion('1.0.0')
.addTag('tyffis')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('api', app, document);
}
async function bootstrapServer(): Promise<Server> {
if (!cachedServer) {
try {
const expressApp = express();
const adapter = new ExpressAdapter(expressApp);
const nestApp = await NestFactory.create(AppModule, adapter);
nestApp.use(eventContext());
await nestApp.init();
setupSwagger(nestApp);
cachedServer = createServer(expressApp, undefined, binaryMimeTypes);
} catch (error) {
return Promise.reject(error);
}
}
return Promise.resolve(cachedServer);
}
export const handler: Handler = async (event: any, context: Context) => {
if (event.path === '/api') {
event.path = '/api/';
}
event.path = event.path.includes('swagger-ui')
? `/api${event.path}`
: event.path;
cachedServer = await bootstrapServer();
return proxy(cachedServer, event, context, 'PROMISE').promise;
};
I had the same problem before with typeorm. My solution was to manually listed entities in the configuration file. So I have two kind of settings.
``export const typeOrmConfig: TypeOrmModuleOptions = {
entities: [${__dirname}/../*/.entity{.ts,.js}`],
...typeOrmConfigGeneral,
};
export const typeOrmConfigServerless: TypeOrmModuleOptions = {
entities: [
Category,
Comment,
Discussion,
],
...typeOrmConfigGeneral,
};
``
I choose the configuration based on someenv`.
Do you use typeorm?
Yes I use typeorm, your solution have fixed my problem concerning the entity :) ! But my swagger documentation still don't work..

Here is my serverless.yml
functions:
index:
handler: src/lambda.handler
events:
- http:
cors: true
path: '/{proxy+}'
method: any
Did I miss something in my lambda.tsupper ?
Show the entire serverless.yml, please.
Here it is:
service: tyffis-backend-test
provider:
name: aws
runtime: nodejs12.x
region: us-east-1
stage: dev
role: LambdaRole
memorySize: 512
vpc:
securityGroupIds:
- sg
subnetIds:
- ids
environment:
TYPEORM_HOST: ${self:custom.AURORA.HOST}
TYPEORM_PORT: ${self:custom.AURORA.PORT}
TYPEORM_USER: ${self:custom.USERNAME}
TYPEORM_PASSWORD: ${self:custom.PASSWORD}
TYPEORM_DB: ${self:custom.DB_NAME}
JWT_SECRET: secret
plugins:
- serverless-plugin-typescript
- serverless-plugin-optimize
- serverless-offline
package:
individually: true
custom:
DB_NAME: db_name
USERNAME: user
PASSWORD: pwd
AURORA:
HOST:
Fn::GetAtt: [AuroraRDSCluster, Endpoint.Address]
PORT:
Fn::GetAtt: [AuroraRDSCluster, Endpoint.Port]
optimize:
external: ['swagger-ui-dist']
resources:
Resources:
LambdaRole: ${file(./infra-serverless/LambdaRole.yml)}
AuroraRDSCluster: ${file(./infra-serverless/AuroraRDSCluster.yml)}
functions:
index:
handler: src/lambda.handler
events:
- http:
cors: true
path: '/{proxy+}'
method: any
All my other routes work, I have authentication flow with jwt, I have no problem with them
Try with:
functions:
main:
handler: src/lambda.handler
events:
- http:
method: any
path: /{any+}
It finally work !! 馃槃
The problem was here:
lambda.ts
await nestApp.init();
setupSwagger(nestApp);
I copied https://gist.github.com/csakbalint/7fe406bd1b15124180a988c87d57cf9b from the original author to make my test but nestApp init has to be call before the setupSwagger function..
setupSwagger(nestApp);
await nestApp.init();
Thank you very much for your time @plorencrstit ! I Appreciate it!
@csakbalint there is an error in your gist, look upper you switched your setupSwagger function with await nestApp.init(); one.
@plorencrstit Thank you very much, you saved my day!!
Hello guys!
I have the same problem, but in serveless offline, the swagger works. When I access the aws endpoint, he didn't work. My lambda is similar of @nathanagez. Anyone can help me?
Most helpful comment
I had the same problem before with
typeorm. My solution was to manually listed entities in the configuration file. So I have two kind of settings.``
export const typeOrmConfig: TypeOrmModuleOptions = { entities: [${__dirname}/../*/.entity{.ts,.js}`],...typeOrmConfigGeneral,
};
export const typeOrmConfigServerless: TypeOrmModuleOptions = {
entities: [
Category,
Comment,
Discussion,
],
...typeOrmConfigGeneral,
};
``
I choose the configuration based on someenv`.Do you use
typeorm?