AWS API Gateway Service Integrations

AWS API Gateway is a cloud scale API service that is an integration point for AWS services or third party services. The
service is very easy to use. First define an OpenAPI specification, then define integrations for the OpenAPI specification
and deploy the specification using CloudFormation. API Gateway supports five types of integrations:

  • mock: for integration with API Gateway without invoking any backend
  • aws: for integrating with AWS services, while allowing transformations
  • aws_proxy: for integrating with AWS Lambda
  • http: for integrating with HTTP backends, while allowing transformations
  • http_proxy: for integrating with HTTP backends

We’ll look at all of the integration types today

aws-cfn-update

“AWS API Gateway makes it easy for developers to create, publish, maintain and monitor secure APIs at any scale”, according
to the official documentation. Although this is true, it is far from trivial to
create an API using CloudFormation templates. The CloudFormation template will contain both an OpenAPI specification, AWS extensions to the
OpenAPI specification and the AWS infrastructure specification to create.

To make developing APIs easier, binx.io created a tool called aws-cfn-update.
The utility updates CloudFormation templates and merges OpenAPI specification with the AWS extensions and then merges the
result into the CloudFormation templates. The utility also supports merging lambda code into CloudFormation, if the code does
not exceed 4000 characters and the language is either Python or Node.js. The utility makes it possible to create projects that
separates specifications and allows for maintainable API projects.

Example Project

The example project shows a project that consists
of a number of project that shows how to create and use each integration type.

OpenAPI specification

API Gateway supports both OpenAPI v2.0 aka. ‘swagger’,
and OpenAPI v3.0. The OpenAPI Specification makes it
easy to define resources, methods and responses for the API. Project 01-swagger
shows an example project that only creates the API Gateway Method requests. There are no integrations configured in this project.
The OpenAPI specification is available in the directory swagger/swagger.yaml.

Type:

  • make merge-swagger: to merge the OpenAPI specification with CloudFormation
  • make deploy: to deploy the project
  • make delete: to delete the project

Mock Integration

Project 02-mock-integration shows
how to setup ‘mock’ integrations. Mock integrations generate API responses from API Gateway directly, without the need for an integration backend.
Mock integrations are great to generate static responses like CORS responses for a POST request. The AWS extensions to the OpenAPI specification
are in the directory swagger/aws-extensions.yaml An example mock integration:

  x-amazon-apigateway-integration:
    responses:
      default:
        statusCode: '200'
        responseParameters:
          method.response.header.Content-Type: "'application/json'"
          method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
          method.response.header.Access-Control-Allow-Methods : "'*'"
          method.response.header.Access-Control-Allow-Origin : "'*'"
        responseTemplates:
          application/json: |-
            [{
              "id": 1,
              "name": "Superman"
             },
             {
               "id": 2,
               "name": "Batman"
             }]
    passthroughBehavior: when_no_match
    requestTemplates:
      application/json: |-
        {
          "statusCode": 200
        }
    type: mock

The mock responds with a HTTP ‘200’ and a list of heroes in JSON format.

HTTP Integration

Project 03-http-integration shows
how to setup ‘http’ integrations. Http integrations are useful when an API method must be integrated with a HTTP endpoint like eg. a utility
service on the Internet or a Http service in the VPC. An example HTTP integration:

  x-amazon-apigateway-integration:
    responses:
      default:
        statusCode: '200'
        responseParameters:
          method.response.header.Content-Type: "'application/json'"
          method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
          method.response.header.Access-Control-Allow-Methods : "'*'"
          method.response.header.Access-Control-Allow-Origin : "'*'"
    passthroughBehavior: when_no_match
    uri: 'https://httpbin.org/anything'
    httpMethod: GET
    type: http_proxy

The http integration calls https://httpbin.org/ with a ‘GET’ and responds with a HTTP ‘200’. The integration type
can be either ‘http_proxy’ or ‘http’.

AWS Proxy (Lambda) Integration

Project 04-lambda-integration shows
how to setup ‘aws_proxy’ integrations. Creating a lambda is more involved. When using Python, the lambda can be inlined in the CloudFormation
template when code is less than 4kB. To support good programming practices, the code should be testable and separated from the CloudFormation template.
The utility aws-cfn-update can merge the lambda code with the CloudFormation template when
the stack should be deployed. For lambda integration, API Gateway must have a role in order to invoke the lambda:

  APIGatewayInvokeLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: apigateway.amazonaws.com
          Action: sts:AssumeRole
          Condition: {}
      Path: /
      Policies:
      - PolicyName: ApiGateway
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action:
            - lambda:InvokeFunction
            Resource:
            - '*'

The ‘aws_proxy’ integration:

  x-amazon-apigateway-integration:
    responses: {}
    uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaHandler.Arn}/invocations
    credentials: !GetAtt APIGatewayInvokeLambdaRole.Arn
    passthroughBehavior: when_no_match
    httpMethod: POST
    type: aws_proxy

Note that the ‘aws_proxy’ integration points to the ‘arn’ of the lambda. The credentials for API Gateway is defined by the
‘APIGatewayInvokeLambdaRole’.

AWS Service Integration

Project 05-aws-service-integration shows
how to setup ‘aws’ service integration. API gateway can invoke the API of AWS services like eg. DynamoDB. API Gateway must have
a role in order to invoke DynamoDB:

  APIGatewayRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: apigateway.amazonaws.com
          Action: sts:AssumeRole
          Condition: {}
      Path: /
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess

The ‘aws’ integration:

  x-amazon-apigateway-integration:
    credentials: !GetAtt APIGatewayRole.Arn
    uri: !Sub "arn:aws:apigateway:${AWS::Region}:dynamodb:action/Scan"
    responses:
      default:
        statusCode: "200"
        responseTemplates:
          application/json: |-
            [
            #foreach ($item in $input.path('$.Items'))
            {
                "id": "$item.id.N",
                "name": "$item.name.S"
            }
            #if($foreach.hasNext), #end
            #end
            ]
    requestTemplates:
      application/json: !Sub |
        {
            "TableName": "${HeroesTable}",
            "ScanFilter": {
              "name": {
                "AttributeValueList":[ {"S":"$input.params('name')"} ],
                 "ComparisonOperator": "CONTAINS"
              }
            }
        }
    passthroughBehavior: when_no_templates
    httpMethod: POST
    type: aws

The ‘aws’ service integation describes which API to invoke, eg. the DynamoDB ‘Scan’ API. The requestTemplate
creates an API request and uses a parameter from the request. The DynamoDB ‘Scan’ response will be converted by the
responseTemplate to a json response and uses Velocity Template Language syntax.

Conclusion

AWS Gateway Integrations makes it easy to integrate backends with an API specification. API Gateway can integrate with
AWS services (aws), http services (http, http_proxy), Lambda (aws_proxy), and can directly respond (mock).
aws-cfn-update allows us to separate all specifications in files and merge
them into a CloudFormation template when the stack is deployed. This allows for maintainable projects and reusable scripts.

Share this article: Tweet this post / Post on LinkedIn