skip to Main Content

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


  1. Chosen as BEST ANSWER

    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 and express via node_modules rather than having those modules bundled into the generated JS.


  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search