By using AWS re:Post, you agree to the AWS re:Post Terms of Use

CloudFormation Template for API Gateway Integration with DynamoDB

0

Where can I find documentation for CF where an API Gateway is integrated with a DynamoDB?

3 Answers
0

To create a CloudFormation template that integrates API Gateway with DynamoDB, you'll need to combine several AWS resources and configurations. While there isn't a single, specific template dedicated to this integration, you can build one using the following components:

  1. Create an API Gateway REST API resource (AWS::ApiGateway::RestApi)
  2. Define the necessary API Gateway resources and methods (AWS::ApiGateway::Resource, AWS::ApiGateway::Method)
  3. Set up a DynamoDB table (AWS::DynamoDB::Table)
  4. Configure the API Gateway integration with DynamoDB using mapping templates

For the API Gateway to DynamoDB integration, you'll need to use mapping templates to transform the incoming API requests into DynamoDB operations, and to transform the DynamoDB responses back to the desired API response format. These mapping templates use Apache Velocity Template Language (VTL) syntax.

When setting up the integration, you'll need to ensure that API Gateway has the necessary permissions to interact with DynamoDB. This typically involves creating an IAM role with appropriate policies.

To get started, you can refer to existing CloudFormation templates that deploy API Gateway and DynamoDB separately, and then combine and modify them to create the integration. The AWS Media Services Application Mapper (MSAM) solution, for example, provides templates that include both API Gateway and DynamoDB resources, which could serve as a starting point for your integration.

Remember to grant appropriate permissions, handle different data types correctly, and thoroughly test your integration to ensure it works as expected.

While creating a direct integration between API Gateway and DynamoDB can offer benefits like improved performance and reduced costs, it also requires careful configuration and thorough understanding of both services.

Sources
Community | Using API Gateway mapping templates for direct DynamoDB integrations
AWS CloudFormation templates - Media Services Application Mapper on AWS

profile picture
answered a month ago
0
profile picture
EXPERT
answered a month ago
0

Here is an example of a Rest API for DynamoDB using CFN:

AWSTemplateFormatVersion: 2010-09-09
Description: An Amazon API Gateway REST API that integrates with an Amazon DynamoDB table. (uksb-1tthgi812) (tag:apigw-rest-api-dynamodb)
Parameters:
  AppName:
    Type: String
    Default: api-music
    Description: Name of application.
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
Resources:
  DynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      TableName: Music
      # A list of attributes that describe the key schema for the DynamoDB table and indexes.
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
        - AttributeName: artist
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
      GlobalSecondaryIndexes:
        - IndexName: Artist-Index
          KeySchema:
            - AttributeName: artist
              KeyType: HASH
          Projection:
            ProjectionType: INCLUDE
            NonKeyAttributes:
              - album
          ProvisionedThroughput:
            ReadCapacityUnits: 5
            WriteCapacityUnits: 5
  APIGatewayRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
      Policies:
        - PolicyName: APIGatewayDynamoDBPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'dynamodb:PutItem'
                  - 'dynamodb:Query'
                # Including * in the resource Arn allows access to the DynamoDB table and indexes
                Resource: !Sub
                  - '${varTableArn}*'
                  - varTableArn: !GetAtt DynamoDBTable.Arn
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: !Sub '${AppName}'
      ApiKeySourceType: HEADER
  MusicResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'music'
  MusicMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref MusicResource
      HttpMethod: POST
      ApiKeyRequired: true
      AuthorizationType: NONE
      Integration:
        Type: AWS
        Credentials: !GetAtt APIGatewayRole.Arn
        # Should always be POST when integrating with AWS services
        IntegrationHttpMethod: POST
        # More info: https://docs.aws.amazon.com/apigateway/api-reference/resource/integration/
        Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:dynamodb:action/PutItem'
        PassthroughBehavior: WHEN_NO_TEMPLATES
        RequestTemplates:
          # Build the structure of the request that is sent when calling DynamoDB PutItem
          # Using single-line, stringified JSON as the mapping template
          # Example body when making API request: {"artist": "The Beatles", "album": "Abbey Road"}
          # Use the unique id of the API context variable (eg: $context.requestId) as the DynamoDB item id
          application/json: "{\"TableName\":\"Music\",\"Item\":{\"id\":{\"S\":\"$context.requestId\"},\"artist\":{\"S\":\"$input.path('$.artist')\"},\"album\":{\"S\":\"$input.path('$.album')\"}}}"
        IntegrationResponses:
          - StatusCode: '200'
            ResponseTemplates:
              application/json: "{}"
      MethodResponses:
        - StatusCode: '200'
  MusicArtistResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !Ref MusicResource
      PathPart: '{artist}'
  MusicArtistMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref MusicArtistResource
      HttpMethod: GET
      ApiKeyRequired: true
      AuthorizationType: NONE
      RequestParameters:
        # Determines whether the path parameter (eg: artist) is required
        method.request.path.artist: true
      Integration:
        Type: AWS
        Credentials: !GetAtt APIGatewayRole.Arn
        # Should always be POST when integrating with AWS services
        IntegrationHttpMethod: POST
        # More info: https://docs.aws.amazon.com/apigateway/api-reference/resource/integration/
        Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:dynamodb:action/Query'
        PassthroughBehavior: WHEN_NO_TEMPLATES
        RequestParameters:
          integration.request.path.artist: method.request.path.artist
        RequestTemplates:
          # Build the structure of the request that is sent when calling DynamoDB Query
          # Using single-line, stringified JSON as the mapping template
          # Use $util.urlDecode($input.params('pathname')) to decode if the url path value contains spaces
          # A + or %20 may be used as a space in the url
          application/json: "{\"TableName\":\"Music\",\"IndexName\":\"Artist-Index\",\"KeyConditionExpression\":\"artist=:v1\",\"ExpressionAttributeValues\":{\":v1\":{\"S\":\"$util.urlDecode($input.params('artist'))\"}}}"
        IntegrationResponses:
          - StatusCode: '200'
            ResponseTemplates:
              # Modify the response of the DynamoDB Query before sending back to the caller
              # Using single-line Velocity Template Language (VTL) code as the mapping template
              # \n represents a new line, \t represents a tab character, \" represents a single quote character
              # Example response: {"music":[{"id":"38bfb57e-a5a8-4fed-9a4f-391d66d5e987","artist":"The Beatles","album":"Abbey Road"}]}
              application/json: "#set($inputRoot = $input.path('$'))\n{\n\t\"music\": [\n\t\t#foreach($field in $inputRoot.Items) {\n\t\t\t\"id\": \"$field.id.S\",\n\t\t\t\"artist\": \"$field.artist.S\",\n\t\t\t\"album\": \"$field.album.S\"\n\t\t}#if($foreach.hasNext),#end\n\t\t#end\n\t]\n}"
      MethodResponses:
        - StatusCode: '200'
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - MusicArtistMethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
  ApiKey:
    Type: 'AWS::ApiGateway::ApiKey'
    DependsOn:
      - ApiDeployment
    Properties:
      Enabled: true
      Name: !Sub '${AppName}-apikey'
      StageKeys:
        - RestApiId: !Ref Api
          StageName: !Sub '${StageName}'
  ApiUsagePlan:
    Type: 'AWS::ApiGateway::UsagePlan'
    DependsOn:
      - ApiDeployment
    Properties:
      ApiStages:
        - ApiId: !Ref Api
          Stage: !Sub '${StageName}'
      Throttle:
        RateLimit: 500
        BurstLimit: 1000
      UsagePlanName: !Sub '${AppName}-usage-plan'
      Quota:
        Limit: 10000
        Period: MONTH
  ApiUsagePlanKey:
    Type: 'AWS::ApiGateway::UsagePlanKey'
    Properties:
      KeyType: API_KEY
      KeyId: !Ref ApiKey
      UsagePlanId: !Ref ApiUsagePlan
Outputs:
  ApiRootUrl:
    Description: Root Url of the API
    Value: !Sub 
      - 'https://${ApiId}.execute-api.${AWS::Region}.amazonaws.com/${StageName}'
      - ApiId: !Ref Api
  ApiKeyId:
    Description: API Key Id
    Value: !Ref ApiKey

Learn more here: https://github.com/aws-samples/serverless-patterns/tree/main/apigw-rest-api-dynamodb

profile pictureAWS
EXPERT
answered a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions