Skip to content

Instantly share code, notes, and snippets.

@johnbeech
Created March 8, 2023 10:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnbeech/8373a030685f2c216e9dca9e09e863a5 to your computer and use it in GitHub Desktop.
Save johnbeech/8373a030685f2c216e9dca9e09e863a5 to your computer and use it in GitHub Desktop.
Generate Open API spec from AWS API Gateway
import path from 'node:path'
import { Duration } from 'aws-cdk-lib'
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'
import { Runtime } from 'aws-cdk-lib/aws-lambda'
import { Construct } from 'constructs'
import { PolicyStatement } from 'aws-cdk-lib/aws-iam'
export const createOpenAPILambda = (scope: Construct): NodejsFunction => {
const apiInformationPolicy = new PolicyStatement({
actions: ['apigateway:GET'],
resources: ['arn:aws:apigateway:*::/restapis/*/stages/*/exports/*']
})
const lambda = new NodejsFunction(scope, 'OpenAPIFn', {
memorySize: 256,
timeout: Duration.seconds(5),
runtime: Runtime.NODEJS_16_X,
handler: 'handler',
entry: path.join(__dirname, '../../routes/openapi.ts'),
bundling: {
minify: true,
externalModules: ['aws-sdk']
}
})
lambda.addToRolePolicy(apiInformationPolicy)
return lambda
}
import {
APIGatewayProxyEvent,
APIGatewayProxyResult
} from 'aws-lambda/trigger/api-gateway-proxy'
import { APIGatewayClient, GetExportCommand } from '@aws-sdk/client-api-gateway'
import { lambdaResponse } from './helpers/lambdaResponse'
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
let openapiSpec, error
try {
const client = new APIGatewayClient({
region: 'eu-west-1'
})
const command = new GetExportCommand({
restApiId: event.requestContext.apiId,
stageName: event.requestContext.stage,
exportType: 'oas30'
})
const commandResponse = await client.send(command)
// GetExportCommandOutput: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-api-gateway/interfaces/getexportcommandoutput.html
const decodedBody = new TextDecoder().decode(commandResponse.body)
openapiSpec = JSON.parse(decodedBody)
console.log('Successfully generated Open API spec')
} catch (ex) {
error = (ex as Error).message
console.log('Unable to generate Open API spec, error:', error)
}
const responseData = openapiSpec ?? { message: 'Unable to retrieve or decode OpenAPI Spec', openapiSpec, error, event }
return lambdaResponse(200, JSON.stringify(responseData))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment