AWS - API Gateway - adding query string parameter via mapping template? - amazon-web-services

Is there a way to do this?
My use case
I'm trying to integrate API gateway and SNS, but every guide/tutorial I found get the TopicArn from the gateway incoming requeste, i.e. from the user call, but since my endpoint will push to a single topic I want to avoid this step, having the API gateway adding it (hardcoded) to the integration request.
AFAIK the only way to do this is via mapping template, is that right?

It was easy and probably I was making some typos at the beginning, so that's why I wasn't succeeding.
AWS::ApiGateway::Method Integration property docs
Amazon API Gateway API request and response data mapping reference
Cloudformation template relevant code
Resources:
ApiGatewayMethod:
Type: AWS::ApiGateway::Method
Properties:
Integration:
RequestParameters:
integration.request.querystring.<query-param-name>:
IntegrationResponses:
- StatusCode: '200'<desired value>
MethodResponses:
- StatusCode: '200'
ResponseModels:
application/json: "Empty"

Related

Path parameters ignored by AWS API Gateway using proxy+

I have a REST API on the AWS API Gateway. It has one resource, /{proxy+}, that is configured with the ANY method. The integration request is setup to be a VPC_PROXY, meaning its using a VPC Link. The VPC link is to a network load balancer that is fronting an app I have running on an ECS cluster using Fargate.
When using the console's option to test the API, I can confirm that requests are reaching my app but the resource being requested is always / according to my logging. If I attempt to set the {proxy} value in the method test screen on the console, it seems like my app only ever gets requests for /. If I set {proxy} to something like widget/5, the response I receive is as if I was request /.
I'm wondering if there is some way to troubleshoot this, scouring the AWS documentation I can't figure out where I'm going wrong with my setup.
In your integration, the endpoint URL should be http://loadbalancerurl/{proxy}. I couldn't find any documentation specifically for VPC Link integration, but there is a tutorial for HTTP proxy integration which has similar steps.
If you are using openapi spec, the integration section would look something like this:
x-amazon-apigateway-integration:
uri: "http://loadbalancerurl/{proxy}"
responses:
default:
statusCode: "200"
requestParameters:
integration.request.path.proxy: "method.request.path.proxy"
passthroughBehavior: "when_no_match"
connectionType: "VPC_LINK"
connectionId: "your-vpclink-id"
httpMethod: "ANY"
type: "http_proxy"
When using the console, integration.request.path.proxy: "method.request.path.proxy" mapping was added automatically when I added {proxy} to my endpoint URL.
What works for me is by adding the following properties:
Resources:
APIGWProxyMethod:
Type: AWS::ApiGateway::Method
Properties:
RequestParameters:
method.request.path.proxy: true # enable proxy
Integration:
RequestParameters:
integration.request.path.proxy: method.request.path.proxy # map method proxy param to integration proxy param
... # the rest of integration property
... # other properties
Articles that helped:
https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-proxy-path-character-error/
https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-proxy-path-parameter-error/

Unable to configure Method Response and Integration Response using AWS SAM

I am trying to deploy the api and lambda function using SAM. But the Method Response and Integration Response are empty. I am aiming to configure the api-gateway like below picture. In this I have manually configured the api-gateway and its working but when I use the SAM to generate the api-gateway it doesn't shpes the Method Response and Integration Response.
Without Sam:
With Sam:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 500
MemorySize: 5000
Resources:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
GatewayResponses:
DEFAULT_4xx:
ResponseParameters:
Headers:
Access-Control-Expose-Headers: "'WWW-Authenticate'"
Access-Control-Allow-Origin: "'*'"
InferenceFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Events:
Inference:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /zero-shot-classification
Method: post
RestApiId: !Ref MyApi
Metadata:
Dockerfile: Dockerfile
DockerContext: ./zero-shot-classification
DockerTag: zero-shot-classification
The difference you see is the difference between how the payload is sent to the lambda and how API gateway processes the response from the lambda. Seeing as in your CloudFormation you do not specify a specification for your API endpoints, AWS SAM will construct this based on the events from your functions. However, AWS SAM will always use the LAMBDA_PROXY integration type, while you seem to be wanting to use the LAMBDA integration type.
I'd suggest you take your manually created API gateway and export it to an openapi/swagger definition. This can then be used as DefinitionBody in you MyApi. That way you can specify it uses the LAMBDA integration instead of the LAMBDA_PROXY integration. Don't forget to update the swagger definition so it uses the created function in your cloudformation and not the function that existed when you exported the API.
That being said, the LAMBDA_PROXY way is more widely used and also removes the need for template mappings in your API Gateway. It is also the only integration type for lambdas that is supported in the HTTP API (API Gateway v2), which is a lot cheaper than the classic REST API.

Using AWS api gateway, how to identify which apis are configured using Lambda proxy integration or Lambda non-proxy (custom) integration

I have APIs configured in AWS API gateway (few with lambda integration and few with lambda proxy integration).
We have decided to go ahead only with lambda proxy integration as it is easy to deploy and maintain. Have exported json file using "Swagger + API Gateway Extensions".
How to identify which endpoints uses lambda integrations from the json file.
Do we have to manually open each endpoint in API Gateway UI and check if it has lambda proxy enabled or there is a better way to identify?
Thanks.
If you look in the Swagger file with custom extensions, each endpoint/method should have a property called x-amazon-apigateway-integration. Underneath that there will be another property named type.
The value for endpoints without Lambda Proxy Integration will be aws and the lambdas with Proxy Integration will be aws_proxy
paths:
# This is not a lambda proxy integration
/v1/noproxy:
get:
produces:
- "application/json"
responses: {}
x-amazon-apigateway-integration:
uri: "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:****:function:***/invocations"
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws"
# This is a lambda proxy integration
/v1/myproxyintegration:
post:
responses: {}
security:
- sigv4: []
x-amazon-apigateway-integration:
uri: "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:*****:function:***/invocations"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
type: "aws_proxy"

How to define calling a state machine from an API gateway in AWS SAM syntax

I am trying to figure out the correct definition for my aws sam template for calling a state machine from an api proxy request. Can this be done using AWS::Serverless::Api and a swagger definition? I have this call now that goes to a lambda and Id like to replace it with my state machine
paths:
"/{userUd}":
any:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${userFunction.Arn}/invocations
responses: {}
Or must I use the RestAPI gateway model? And if so an example would be amazing as I am having difficulty finding any.

Rest API using Lambda and API Getway

I start study AWS serverless using lambda and API Getway, So I was thinking to create a REST API for a sample project. I noticed that in API Getway, we only can create the http methods which can trigger lambda functions, So I'm not sure if I get this right but, do we need one lambda function for each api route? or we can handle it somehow using one lambda function.
For example, lets say my project need api for below list :
Login
Register
GetUserData
Then if I going to make this by using API Getway and Lambda, I need to have 3 Lambda functions?
Like if I want create API for those mentioned above, it should be something like this for the endpoints ?
https://API_GETWAY_DOMAIN/STAGE/LAMBDA_FUNCTION_FOR_LOGIN
https://API_GETWAY_DOMAIN/STAGE/LAMBDA_FUNCTION_FOR_REGISTER
https://API_GETWAY_DOMAIN/STAGE/LAMBDA_FUNCTION_FOR_GET_USER_DATA
And is there any way to send multi http request to one lambda function, and handle each one of them inside the lambda?
It is possible to have multiple API Gateway routes direct to the same Lambda function. How to set that up depends on how you're maintaining your infrastructure.
For example, if you're using CloudFormation with the Serverless Application Model (SAM), which I recommend since it's probably the most straightforward way to keep track of serverless infrastructure (and infrastructure as code = awesome), you would define your AWS::Serverless::Function with a separate API Gateway source event for each route you define in your AWS::Serverless::Api.
Something like the following:
YourApi:
Type: AWS::Serverless::Api
Properties:
...
DefinitionBody:
swagger: 2.0
...
paths:
'/Login':
post:
x-amazon-apigateway-integration:
# APIG->Lambda requests are always POST
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${YourLambda.Arn}/invocations
'/Register':
post:
x-amazon-apigateway-integration:
# APIG->Lambda requests are always POST
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${YourLambda.Arn}/invocations
'/GetUserData':
get:
x-amazon-apigateway-integration:
# APIG->Lambda requests are always POST
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${YourLambda.Arn}/invocations
YourLambda:
Type: AWS::Serverless::Function
Properties:
...
Events:
login:
Type: Api
Properties:
Path: '/Login'
Method: post
RestApiId: {Ref: YourApi}
register:
Type: Api
Properties:
Path: '/Register'
Method: post
RestApiId: {Ref: YourApi}
getUserData:
Type: Api
Properties:
Path: '/GetUserData'
Method: get
RestApiId: {Ref: YourApi}
Keep in mind, though, that there are pros and cons to consolidating routes into one Lambda function. This StackOverflow question/answer explores that, but I'd like to add a few more benefits to separated Lambda functions:
Clearer metrics on how often your routes are getting called - You get invocations/errors/etc. metrics in CloudWatch for each Lambda function out-of-the-box, so separating them can make it easy to see how often people are registering versus logging in, etc.
More granular alarming - You can set different latency/error/etc. thresholds for different routes, and if an alarm goes off, you know exactly which Lambda function it's for.