I’m trying to publish the documentation for an API I’ve developed by means of swagger-ui
. Since the API is hosted on AWS API Gateway, I have developed the below Lambda to handle the /swagger-simpler
API endpoint. I’ve confirmed that I’m successfully retrieving the docs, but when I go to the /swagger-simpler
endpoint, I get the error: Uncaught SyntaxError: expected expression, got '<'
in swagger-ui-bundle.js
. When I pull up swagger-ui-bundle.js
, it’s the exact same HTML as I get when I pull up the /swagger-simpler
endpoint.
What am I doing wrong?
Swagger Lambda:
/** @format */
import 'source-map-support/register'
import express from 'express'
import serverless from 'serverless-http'
import swaggerUi from 'swagger-ui-express'
import { Handler } from 'aws-lambda'
import { APIGatewayClient, GetExportCommand } from '@aws-sdk/client-api-gateway'
const app = express()
const apiGateway = new APIGatewayClient({})
export const handler: Handler = async (event, context) => {
const apiId = event.requestContext.apiId
const stage = event.requestContext.stage
console.debug('From request context', { apiId, stage })
let swaggerJson: swaggerUi.JsonObject
try {
swaggerJson = await getSwaggerJson(apiId, stage)
} catch (e) {
console.error('Failed to retreive Swagger JSON', e)
throw new Error('Failed to retreive Swagger JSON')
}
console.debug('Got Swagger doc object', { swaggerJson })
app.use('/swagger-simpler', swaggerUi.serve, swaggerUi.setup(swaggerJson))
console.debug('here')
const handler = serverless(app)
console.debug('got handler', { handler })
const ret = await handler(event, context)
console.debug('handler returned', { ret })
return ret
}
const getSwaggerJson = async (
restApiId: string,
stageName: string
): Promise<swaggerUi.JsonObject> => {
const params = {
exportType: 'oas30',
restApiId,
stageName,
accepts: 'application/json',
}
const res = await apiGateway.send(new GetExportCommand(params))
console.debug('GetExportCommand successful', { res })
let swaggerJson: string
if (res.body) {
swaggerJson = Buffer.from(res.body).toString()
} else {
throw new Error('Empty response body from GetExportCommand')
}
console.debug('Got Swagger JSON', { swaggerJson })
return JSON.parse(swaggerJson)
}
2
Answers
It turned out to be a CDK issue. See the article I wrote about it for details, but basically I needed to install
swagger-ui-express
andexpress
vianode_modules
rather than having those modules bundled into the generated JS.Use S3 instead of Lambda to host the auto generated Swagger docs from API Gateway. Within S3 you can host a static website with a clicks.
Just make sure this meets your security needs.