Skip to content

Proposal: API Gateway Integration Resource #1429

@brysontyrrell

Description

@brysontyrrell

Description:

This is related to #651 where it was requested to have a way to apply an Event to certain CloudFormation Resources. The ask was to simplify the integration of API Gateway to other AWS services like SQS, SNS, DynamoDB, etc.

To do this today, one needs to pour through API Gateway documentation, posted online examples, and stitch together a full swagger definition for their API. The simplify of SAM is lost when the swagger definition is brought into play.

I'd like to propose the introduction of a new SAM type meant to represent an AWS service integration to an API Gateway and generate the required swagger elements/extensions for the developer.

Current Example

Here is a template from an example I posted in that issue (integrating an SQS queue with an API Gateway):

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: >-
  Create an API Gateway integrated with an SQS queue that is processed by a
  Lambda function as messages are populated.
Resources:

  QueueApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionBody:
        swagger: "2.0"
        info:
          title: !Ref AWS::StackName
        paths:
          "/":
            post:
              consumes:
              - "application/json"
              produces:
              - "application/json"
              responses:
                "200":
                  description: "200 response"
                  schema:
                    $ref: "#/definitions/Empty"
              x-amazon-apigateway-integration:
                credentials: !GetAtt QueueApiGatewayRole.Arn
                uri: !Sub "arn:aws:apigateway:${AWS::Region}:sqs:path//"
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
                requestTemplates:
                  application/json: !Sub "Action=SendMessage##\n&QueueUrl=$util.urlEncode('${ApiQueue}')##\n\
                    &MessageBody=$util.urlEncode($input.body)##\n"
                passthroughBehavior: "never"
                httpMethod: "POST"
                type: "aws"
        definitions:
          Empty:
            type: "object"
            title: "Empty Schema"

  ApiQueue:
    Type: AWS::SQS::Queue

  QueueApiGatewayRole:
    Type: AWS::IAM::Role
    Properties:
      Path: "/"
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
      Policies:
        - PolicyName: ApiQueuePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - sqs:ReceiveMessage
                  - sqs:SendMessage
                Resource: !GetAtt ApiQueue.Arn

Proposed Example

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31

Resources:

  QueueApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod

  ApiQueue:
    Type: AWS::SQS::Queue

  QueueApiIntegration:
    Type: AWS::Serverless::ApiIntegration
    Properties:
      RestApiId: !Ref QueueApiGateway
      Path: /
      Method: post
      Service:
        Type: SQS
        Properties:
          QueueUrl: !Ref ApiQueue
          Method: post

I won't pretend to know much about performing these service integrations. The idea with my proposed model is to strip away the swagger work and match how other SAM resources operated. All of the information required to infer the SQS integration in swagger are present in the Service payload (assuming the intent of this integration is to sent the HTTP payload as the MessageBody).

This resource would support multiple service types much like Events with functions. If a RestApiId is not provided it would use the implicit API created by SAM. The resource policy would be generated automatically using the !Refs between the API and the queue.

I think there's a huge opportunity for SAM to make these types of service integrations easier to adopt for AWS developers. While we hear and know that having a Lambda in-between an API and a service can be a waste, or unnecessary, it's usually the easier path.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions