Skip to content
Himanshu Patil
TwitterInstagramGithubLinkedin

Programmatically convert api gateway sync invoke lambda to async

AWS-api-gateway, AWS-lambda, SAM2 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);
});