Programmatically convert api gateway sync invoke lambda to async
— AWS-api-gateway, AWS-lambda, SAM — 2 min read
const { APIGatewayClient, GetResourcesCommand,
GetMethodResponseCommand, PutMethodResponseCommand,
PutIntegrationCommand,
PutIntegrationResponseCommand,
CreateDeploymentCommand,} = require('@aws-sdk/client-api-gateway');
const { LambdaClient, GetFunctionCommand } = require('@aws-sdk/client-lambda');
console.log('process.argv', process.argv);const accessKeyId = process.argv[2].trim();const secretAccessKey = process.argv[3].trim();const region = process.argv[4].trim();const functionName = process.argv[5].trim();const fnRegion = process.argv[6].trim();const stageName = process.argv[7].trim();const restApiId = process.argv[8].trim();
const cred = { region, credentials: { accessKeyId: accessKeyId, secretAccessKey: secretAccessKey, },};const lambdaClient = new LambdaClient(cred);
const apiGatewayClient = new APIGatewayClient(cred);
const jsonTemplate = { 'application/json': `#set($allParams = $input.params()) { "body" : $input.body, "httpMethod": "$context.httpMethod", "path" : "$context.resourcePath", "headers": { #foreach($param in $input.params().header.keySet()) "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end #end }, "queryStringParameters": { #foreach($param in $input.params().querystring.keySet()) "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end #end }, "pathParameters": { #foreach($param in $input.params().path.keySet()) "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end #end } }`,};
const getResourcesCommand = new GetResourcesCommand({ restApiId });
const getMethodResponseCommand = (resourceId) => new GetMethodResponseCommand({ restApiId, resourceId, httpMethod: 'POST', statusCode: '200', });const putMethodResponseCommand = (resourceId) => new PutMethodResponseCommand({ httpMethod: 'POST', restApiId, resourceId, statusCode: '200', responseParameters: { 'method.response.header.access-control-allow-origin': true, }, });
const putIntegrationCommand = (resourceId, functionArn) => new PutIntegrationCommand({ httpMethod: 'POST', integrationHttpMethod: 'POST', restApiId, resourceId, type: 'AWS', uri: `arn:aws:apigateway:${fnRegion}:lambda:path/2015-03-31/functions/${functionArn}/invocations`, requestParameters: { 'integration.request.header.X-Amz-Invocation-Type': "'Event'", }, requestTemplates: jsonTemplate, });
const putIntegrationResponseCommand = (resourceId) => new PutIntegrationResponseCommand({ restApiId, resourceId, statusCode: '200', httpMethod: 'POST', responseParameters: { 'method.response.header.access-control-allow-origin': "'*'", }, responseTemplates: jsonTemplate, });
const createDeploymentCommand = new CreateDeploymentCommand({ restApiId, stageName,});
const getFunctionCommand = new GetFunctionCommand({ FunctionName: functionName,});
const fun = async () => { const resources = await apiGatewayClient.send(getResourcesCommand); const createResource = resources.items .filter((x) => x.resourceMethods); const functionInfo = await lambdaClient.send(getFunctionCommand); const functionArn = functionInfo.Configuration.FunctionArn;
if (!createResource.length) { console.log('no resource found'); return 'error'; } const promiseArray = createResource.map(async (x) => { const resourceId = x.id;
try { await apiGatewayClient.send(getMethodResponseCommand(resourceId)); } catch (error) { const { httpStatusCode } = error.$metadata; if (httpStatusCode === 404) { await apiGatewayClient.send(putMethodResponseCommand(resourceId)); } }
try { await apiGatewayClient.send(putIntegrationCommand(resourceId, functionArn)); } catch (error) { console.log(error); }
try { await apiGatewayClient.send(putIntegrationResponseCommand(resourceId)); } catch (error) { console.log(error); } });
await Promise.all(promiseArray); return 'ok';};
fun().then(async (x) => { console.log(x); await apiGatewayClient.send(createDeploymentCommand);});