Chris
Chris

Reputation: 305

Adding lambda integration to HttpApi routes with SAM

I am currently attempting to have a AWS::Serverless::HttpApi integrate with a group of AWS::Serverless::Function's. The goal is to define these resources within a SAM template, and define the actual API using a swagger file.

I have my SAM template defined as so:


Resources:
  apiPing:
    Type: AWS::Serverless::Function
    Properties:
      Description: 'Ping'
      CodeUri: ../bin/cmd-api-ping.zip
      Handler: cmd-api-ping
      Runtime: go1.x
      Role:
        Fn::GetAtt: apiLambdaRole.Arn
      Events:
        PingEvent:
          Type: HttpApi
          Properties:
            ApiId: !Ref api
            Path: /ping
            Method: post
  api:
    Type: AWS::Serverless::HttpApi
    Properties:
      StageName: prod
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: swagger.yaml
      AccessLogSettings:
        DestinationArn: !GetAtt accessLogs.Arn
        Format: $context.requestId

And my swagger file:

openapi: 3.0.1
info:
  title: 'API'
  version: 2019-10-13

paths:
  /ping:
    post:
      summary: 'invoke ping'
      operationId: 'apiPing'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PingRequest'
        required: true
      responses:
        '200':
          description: 'Successful'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PongResponse'
      x-amazon-apigateway-integration:
        httpMethod: "POST"
        type: aws_proxy
        uri:
          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${apiPing.Arn}/invocations
        responses:
          default:
            statusCode: "200"
        contentHandling: "CONVERT_TO_TEXT"
        passthroughBehavior: "when_no_match"
components:
  schemas:
    PingRequest:
      description: 'a ping request'
      type: object
      properties:
        ping:
          description: 'some text'
          type: string
    PongResponse:
      description: 'a pong response'
      type: object
      properties:
        pong:
          description: 'some text'
          type: string

This template deploys without any errors, however there is no integration attached to the /ping POST route.

The transformed template in CloudFormation does show a loaded swagger file:

    "api": {
      "Type": "AWS::ApiGatewayV2::Api",
      "Properties": {
        "Body": {
          "info": {
            "version": 1570924800000,
            "title": "API"
          },
          "paths": {
            "/ping": {
              "post": {
                "requestBody": {
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/PingRequest"
                      }
                    }
                  },
                  "required": true
                },
                "x-amazon-apigateway-integration": {
                  "contentHandling": "CONVERT_TO_TEXT",
                  "responses": {
                    "default": {
                      "statusCode": "200"
                    }
                  },
                  "uri": {
                    "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${apiPing.Arn}/invocations"
                  },
                  "httpMethod": "POST",
                  "passthroughBehavior": "when_no_match",
                  "type": "aws_proxy"
                },
                "summary": "invoke ping",
                "responses": {
                  "200": {
                    "content": {
                      "application/json": {
                        "schema": {
                          "$ref": "#/components/schemas/PongResponse"
                        }
                      }
                    },
                    "description": "Successful"
                  }
                },
                "operationId": "apiPing"
              }
            }
          },
          "openapi": "3.0.1",
          "components": {
            "schemas": {
              "PingRequest": {
                "type": "object",
                "description": "a ping request",
                "properties": {
                  "ping": {
                    "type": "string",
                    "description": "some text"
                  }
                }
              },
              "PongResponse": {
                "type": "object",
                "description": "a pong response",
                "properties": {
                  "pong": {
                    "type": "string",
                    "description": "some text"
                  }
                }
              }
            }
          },
          "tags": [
            {
              "name": "httpapi:createdBy",
              "x-amazon-apigateway-tag-value": "SAM"
            }
          ]
        }
      }
    }

I'm trying to understand what I may need to change or add to add the integration to the http api. I can't find any clear explanation in the aws documentation.

Upvotes: 5

Views: 1427

Answers (1)

Chris
Chris

Reputation: 305

I have managed to resolve this. aws::serverless::httpapi creates a AWS::ApiGatewayV2::Api resource. This requires a different integration than the previous versioned ApiGateway.

x-amazon-apigateway-integration has a key defined, payloadFormatVersion. Despite documentation suggesting both 1.0 and 2.0 are supported, it seems 2.0 must be used. As such, my x-amazon-apigateway-integration has become the following (I did clean it up a bit):

x-amazon-apigateway-integration:
  payloadFormatVersion: "2.0"
  httpMethod: "POST"
  type: "aws_proxy"
  uri:
    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${apiPing.Arn}/invocations
  responses:
    default:
      statusCode: "200"
  connectionType: "INTERNET"

And with this, integration is applied upon deployment.

Upvotes: 5

Related Questions