amazon-web-serviceslambdaaws-cloudformationaws-api-gatewayserverless-application-model

SAM API Gateway caching with a method with query parameters


With the following SAM template:

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      CacheClusterEnabled: true
      CacheClusterSize: '0.5'
      MethodSettings:
        - HttpMethod: GET
          CacheTtlInSeconds: 120
          ResourcePath: "/getData"
          CachingEnabled: true
      DefinitionBody:
        swagger: 2.0
        basePath: /Prod
        info:
          title: OutService
        x-amazon-apigateway-policy:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Principal: "*"
              Action: execute-api:Invoke
              Resource:
                - execute-api:/*/*/*
        paths:
          "/getData":
            get:
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws_proxy
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${OutLambda.Arn}/invocations
              responses: {}
      EndpointConfiguration: PRIVATE
      Cors:
        AllowHeaders: "'*'"

Now /getData accepts query parameters e.g. - /getData?path=abcd/efgh with a response 1234.

When I trigger the API with the path /getData?path=abcd/efgh, this is cached correctly - responds with 1234.

However, after I trigger the api with different query params - e.g. /getData?path=uvw/xyz expecting the respons 789 the response cached for the first request is returned - 1234.

How can I make sure that the caching is applied for paths with query params?

Example of a sequence of issued requests and their respective responses:

/getData?path=abcd/efgh -> 1234 is returned and cached at 11:01:01

/getData?path=uvw/xyz -> 789 is returned and cached at 11:01:02

/getData?path=abcd/efgh -> 1234 is returned from the cache at 11:01:20

/getData?path=uvw/xyz -> 789 is returned from the cache at 11:01:31

EDIT

I am trying to utilise the RequestParameters and then map them to CacheKeyParameters as explained in these 2 articles - https://medium.com/@dougmoscrop/i-set-up-api-gateway-caching-here-are-some-things-that-surprised-me-7526d954fbe6 & https://theburningmonk.com/2016/04/serverless-enable-caching-on-query-string-parameters-in-api-gateway/, but both of these use the serverless framework I am unable to figure out how this would fit into my template


Solution

  • The end result in the AWS API Gateway console must display that the set caching checkbox is:

    enter image description here

    We can achieve it like this:

    Resources:
      MyApi:
        Type: AWS::Serverless::Api
        Properties:
          StageName: Prod
          CacheClusterEnabled: true
          CacheClusterSize: '0.5'
          MethodSettings:
            - HttpMethod: GET
              CacheTtlInSeconds: 120
              ResourcePath: "/getData"
              CachingEnabled: true
          DefinitionBody:
            swagger: 2.0
            basePath: /Prod
            info:
              title: OutService
            x-amazon-apigateway-policy:
              Version: "2012-10-17"
              Statement:
                - Effect: Allow
                  Principal: "*"
                  Action: execute-api:Invoke
                  Resource:
                    - execute-api:/*/*/*
            paths:
              "/getData":
                get:
                  # ** Missing param start **
                  parameters:
                    - name: "path"
                      in: "query"
                      required: "false"
                      type: "string"
                  # ** Missing param end **
                  x-amazon-apigateway-integration:
                  # ** Key is cached **
                    cacheKeyParameters:
                      - method.request.querystring.path
                    httpMethod: POST
                    type: aws_proxy
                    uri:
                      Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${OutLambda.Arn}/invocations
                  responses: {}
          EndpointConfiguration: PRIVATE
          Cors:
            AllowHeaders: "'*'"