Set TTL for API Gateway in Swagger - amazon-web-services

I'm using cloudformation, and have enabled caching like this:
Type: AWS::ApiGateway::Stage
Properties:
CacheClusterEnabled: true
CacheClusterSize: 0.5
My methods are taken from swagger. Here's my swagger file for GET
/v1/myPath/{id}:
get:
tags:
- Books
operationId: getBook
parameters:
- name: id
in: path
description: The ID of the book to retrieve
type: integer
format: int32
required: true
- name: custom-header
in: header
type: string
responses:
'200':
x-amazon-apigateway-integration:
type: aws_proxy
httpMethod: POST
uri: arn:aws:apigateway:us-west-1:lambda:path...
passthroughBehavior: when_no_match
requestParameters:
integration.request.header.custom-header: method.request.header.custom-header
cacheKeyParameters:
- method.request.header.custom-header
How can I set the caching TTL for my GET request in my swagger.yaml? I can't seem to find documentation for this.

Referring to documentation,
CacheTtlInSeconds: Integer
CacheTtlInSeconds
The time-to-live (TTL) period, in seconds, that specifies how long API Gateway caches responses.
Required: No
Type: Integer
Reference:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-deployment-stagedescription.html
Hope it helps.
EDIT1:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apitgateway-method-methodresponse.html#cfn-apigateway-method-methodresponse-responseparameters
Cache-Control Documentation:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
Way to add headers to cloudformation,
ResponseParameters
Response parameters that API Gateway sends to the client that called a method. Specify response parameters as key-value pairs (string-to-Boolean maps), with a destination as the key and a Boolean as the value. Specify the destination using the following pattern: method.response.header.name, where the name is a valid, unique header name. The Boolean specifies whether a parameter is required.
Required: No
Type: Mapping of key-value pairs

Related

How to enable cache in AWS APIGateway using OpenApi yaml?

I have a yaml file for the API Gateway integration like this:
/users/{userId}:
get:
description: Get user details
parameters:
- description: Valid user id
in: path
name: userId
required: true
schema:
type: string
responses:
'200':
content: {}
description: Success
headers:
Access-Control-Allow-Origin:
schema:
type: string
'400':
content: {}
description: Invalid user id
security:
- NodeJsAuth: []
summary: Get User Id Details
tags:
- User
x-amazon-apigateway-integration:
connectionId: ${stageVariables.vpcLinkId}
connectionType: VPC_LINK
httpMethod: GET
passthroughBehavior: when_no_match
requestParameters:
integration.request.path.userId: method.request.path.userId
responses:
default:
responseParameters:
method.response.header.Access-Control-Allow-Origin: '''*'''
statusCode: '200'
type: http_proxy
uri: '#{EksElbUri}#/user/{userId}'
I want to enable cache for this method. I know I can enable it manually but I want to do it in YAML file so it could be easier to execute.
I have my stage enabled the cache already (via AWS Console UI). However I could not find anywhere that is mentioning how to enable cache for this method ONLY.
I am aware that once enabled the cache in stage, it will enabled for all GET endpoints and I have many GET endpoints but I only want this one to be cached.
Is there a way that I can specify the cache in OPEN-API so I no need to disable all the other GET endpoint one by one manually?
Thank you.
What will you'll find easier is edit the API in the API GW Console, enabling cache. Deploy the API to your stage. Then go to Stages -> your stage, and export the API in whatever format you are currently editing in. This is what I do saves you having indentation problems, and wasting time trying to find the exact equivalent syntax.
Once you have done that once your file is easier to edit and you can typically figure out the edits you want to make.

AWS API Gateway and Lambda integration with resources on different Cloudformation stacks

I want to integrate a lambda function to an API gateway so that when I do a POST to the path defined on the API gateway the Lambda gets executed and returns a value.
Now, in my current project we currently have 2 Cloudformation templates:
- One that is generic and contains the definition of recourses common to all development environments
- And another non-generic one that deploys different resources depending on the environment passed as a paramater (dev, prod, etc).
In the non generic I have defined the lambda function, as well as the Deployment and Stage.
In the generic CF template I have defined the APIGateway as this:
Resources:
RecargakiApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
Body:
swagger: "2.0"
info:
version: "VersionTimestamp"
title: "Some API"
host: "some.host"
schemes:
- "https"
paths:
/payment:
post:
produces:
- "application/json"
responses:
"200":
description: "200 response"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
credentials:
Fn::ImportValue:
"lambda-credentials-outputvalue-in-another-generic-stack"
uri: !Sub
- "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda::${AWS::Region}:${AWS::AccountId}:function:${lambdaName}/invocations"
- lambdaName: "${stageVariables.lambda_name}"
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
timeoutInMillis: 5000
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
definitions:
Empty:
type: "object"
title: "Empty Schema"
Description: "Desc"
Name: "Name"
EndpointConfiguration:
Types:
- REGIONAL
Now according to the docs on AWS proxy integration it is possible to construct the lambda uri like this:
arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda::<account_id>:function:${stageVariables.<function_variable_name>}/invocations
I tried to construct the uri according to that format but I get this error:
Unable to put integration on 'POST' for resource at path '/payment': Invalid function ARN or invalid uri (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException
In all the examples I've seen, people assume the Lambda function to be integrated is located in the same CF template/stack as the API Gateway resource, but I have no idea how to reference the function's ARN and/or name in the Swagger definition of the API Gateway when the function is actually located in a different CF stack.
I've also tried referencing a stage variable that would contain the full URI like:
uri: "${stageVariables.functionURI}" # the URI would be constructed in the non generic stack in the format stated by the docs
But it fails with:
Unable to put integration on 'POST' for resource at path '/payment': Invalid ARN specified in the request (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException
Any help is greatly appreciated.

Swagger definition for an AWS Api-Gateway Lambda Proxy endpoint

FYI - I've checked similar issues related to this, but none solves my problem.
I'm trying to create the Swagger definition for a number of APIs under AWS Api-Gateway. I'm able to successfully do this for other(POST, GET) endpoints from an auto-generated YAML configuration I downloaded from the API Stage.
But I encountered issues when I tried to do same for an Api-Gateway endpoint with Lambda Proxy Integration: Error from Swagger editor.swagger.io
Below is my YAML definition for the failing endpoint:
swagger: "2.0"
info:
version: "2018-04-18T17-09-07Z"
title: "XXX API"
host: "api.xxx.io"
schemes:
- "https"
parameters:
stage:
name: stage
in: path
type: string
enum: [ staging, production]
required: true
paths:
/env/{stage}/{proxy+}:
x-amazon-apigateway-any-method:
produces:
- "application/json"
parameters:
- $ref: '#/parameters/stage'
- name: "proxy"
in: "path"
required: true
type: "string"
responses: {}
x-amazon-apigateway-integration:
uri: "arn:aws:apigateway:eu-central-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-central-1:xxxxxxxxx:function:environment/invocations"
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
cacheNamespace: "4vbcjm"
cacheKeyParameters:
- "method.request.path.proxy"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
this is inline with AWS Documentation: enter link description here
Please, what am I missing?
At a glance I believe you have an error in your parameters block. If you include a $ref it discards anything in that block that follows it, so your proxy name is getting dropped. I have a similar setup with api-gateway proxying all calls to a lambda and this is my parameters block:
parameters:
- name: "proxy"
in: "path"
required: true
type: "string"
Additionally you may want an authorizer if you're at all worried about DDoS or serving up secure data. That's done by adding a security array as a sibling to parameters, and a securityDefinitions block as a sibling to paths
security:
- authorizer: []
securityDefinitions:
authorizer:
type : "apiKey"
name : "Authorization"
in : "header"
x-amazon-apigateway-authtype : "custom"
x-amazon-apigateway-authorizer : {
type : "request",
authorizerUri : "arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${region}:${account_id}:function:${authorizer_function_name}/invocations",
authorizerResultTtlInSeconds : 58,
identitySource: "method.request.header.authorization",
}
*note I'm publishing swagger as a terraform template, hence the ${} substitution.

AWS API Gateway caching ignores query parameters

I'm configuring the caching on AWS API Gateway side to improve performance of my REST API. The endpoint I'm trying to configure is using a query parameter. I already enabled caching on AWS API Gateway side but unfortunately had to find out that it's ignoring the query parameters when building the cache key.
For instance, when I make first GET call with query parameter "test1"
GET https://2kdslm234ds9.execute-api.us-east-1.amazonaws.com/api/test?search=test1
Response for this call is saved in cache, and when after that I make call another query parameter - "test2"
GET https://2kdslm234ds9.execute-api.us-east-1.amazonaws.com/api/test?search=test2
I get again response for first call.
Settings for caching are pretty simple and I didn't find something related to parameters configuration.
How can I configure Gateway caching to take into account query parameters?
You need to configure this option in the Gateway API panel.
Choose your API and click Resources.
Choose the method and see the
URL Query String session.
If there is no query string, add one.
Mark the "caching" option of the query string.
Perform the final tests and finally, deploy changes.
Screenshot
The following is how we can achieve this utilising SAM:
The end result in the AWS API Gateway console must display that the set caching checkbox is:
The *.yml template for the API Gateway would be:
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:
# ** Parameter(s) can be set here **
parameters:
- name: "path"
in: "query"
required: "false"
type: "string"
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: "'*'"

Use timestamp in AWS API Gateway in the Path Override of the Integration Request

I've been trying to create a method in API Gateway that drops the body of the incoming request into a file/object in an S3 bucket. But I want the method to create a new file each time (so a file with a new name) instead of overwriting the previous one. But I've been struggling to find a way to do it. Anyone has any suggestions/ideas? Something like a timestamp, or a sequence number (or both) to use as a variable in the Path override so that it would become the name of the s3 file. I looked at suggestions to use the X-Amzn-Trace-Id but it doesn't seem to be available in Path override. Anything else I could try? Maybe something in Swagger? I want to achieve it using API Gateway (avoid using a lambda as an extra step) to keep our architecture from getting too complex. Thanks in advance!
You can set the X-Amzn-Trace-Id as the method parameter, then map the parameter to the integration parameter on the path to S3 as the object name .
Example:
---
swagger: "2.0"
info:
version: "2017-12-04T23:03:26Z"
title: "API"
host: "xxxx.execute-api.us-east-1.amazonaws.com"
basePath: "/dev"
schemes:
- "https"
paths:
/:
post:
produces:
- "application/json"
parameters:
- name: "X-Amzn-Trace-Id"
in: "header"
required: false
type: "string"
responses:
200:
description: "200 response"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
credentials: "arn:aws:iam::178779171625:role/api-gate-way"
responses:
default:
statusCode: "200"
requestParameters:
integration.request.path.traceid: "method.request.header.X-Amzn-Trace-Id"
uri: "arn:aws:apigateway:us-east-1:bucketName.s3:path/{traceid}"
passthroughBehavior: "when_no_match"
httpMethod: "PUT"
type: "aws"
definitions:
Empty:
type: "object"
title: "Empty Schema"