API Gateway and Lambda
Tags: aws, serverless
Published: 2020-05-02 16:45:24

Below is an example of how to create API Gateway that trigger Lambda by using 3 difference Infrastructure as Code tools.

**AWS CloudFormation**

Example, https://github.com/MacKittipat/mac-cloudformation-helloworld/blob/master/cloudformation.yaml

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  LambdaFunctionName:
    Type: String
    Default: HelloWorld
Resources:
  # API Gateway
  ApiGatewayRestApiHelloWorld:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: HelloWorldApi
  ApiGatewayResourceHelloWorld:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref ApiGatewayRestApiHelloWorld
      ParentId: !GetAtt ApiGatewayRestApiHelloWorld.RootResourceId
      PathPart: !Ref LambdaFunctionName
  ApiGatewayMethodHelloWorld:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      HttpMethod: ANY
      ResourceId: !Ref ApiGatewayResourceHelloWorld
      RestApiId: !Ref ApiGatewayRestApiHelloWorld
      ApiKeyRequired: false
      AuthorizationType: NONE
      MethodResponses:
        - StatusCode: '200'
      Integration:
        ConnectionType: INTERNET
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunctionHelloWorld.Arn}/invocations'
  ApiGatewayDeploymentHelloWorld:
    DependsOn: ApiGatewayMethodHelloWorld
    Type: 'AWS::ApiGateway::Deployment'
    Properties:
      RestApiId: !Ref ApiGatewayRestApiHelloWorld
      StageName: prod
  # Lambda Function
  LambdaFunctionHelloWorld:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: !Ref LambdaFunctionName
      Code:
        ZipFile: |
          exports.handler = async function(event) {
            const response = {
              statusCode: 200,
              body: "Hello World. Build with CloudFormation",
            };
            return response;
          }
      Handler: index.handler
      Role: {ROLE}
      Runtime: nodejs12.x
  LambdaPermissionHelloWorld:
    Type: 'AWS::Lambda::Permission'
    Properties:
      FunctionName: !GetAtt LambdaFunctionHelloWorld.Arn
      Action: lambda:InvokeFunction
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApiHelloWorld}/*/*/${LambdaFunctionName}'
```

**Serverless Framework**

Example, https://github.com/MacKittipat/mac-serverless-helloearth

```yaml
provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: ap-southeast-1
functions:
  hello:
    handler: handler.helloEarth
    events:
      - http:
          path: HelloEarth
          method: get
```

**AWS CDK**

Example, https://github.com/MacKittipat/mac-cdk-helloplanet

```ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as apiGateway from '@aws-cdk/aws-apigateway';

export class MacCdkHelloplanetStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const functionName = 'HelloPlanet';
    const lambdaFunction = new lambda.Function(this, functionName, {
      runtime: lambda.Runtime.NODEJS_12_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('resources'),
    });

    const gatewayRestApi = new apiGateway.RestApi(this, functionName + 'Api', {
      restApiName: functionName + 'Api',
      deployOptions: {
        stageName: 'prod'
      }
    })

    const gatewayLambdaIntegration = new apiGateway.LambdaIntegration(lambdaFunction, {
      allowTestInvoke: false
    });

    const gatewayResource = gatewayRestApi.root.addResource(functionName);
    gatewayResource.addMethod("GET", gatewayLambdaIntegration)

  }
}
```