AWS API GATEWAY empty body transformation - amazon-web-services

I am facing an issue, I cannot succed to solve it after few hour, I am hopping you guys can help :)
I have this AWS lambda function (using python):
It put item into my dynamodb, when I test directly in lambda it works well
Here is my dynamodb line
I created an API with AWS API GATEWAY as a "POST" type, then I set the integration request as followed :
and Content-Type : application/json
But when I try to test it on API GATEWAY (or postman etc) I get the following error :
I noticed that
But I don't know where the transformation come from neither how to solve it,
Then again, thank you so much for any help !

Related

Geolocation service with AWS API Gateway and Lambda

What we are trying to do
We are trying to set up a very simple Geolocation service with API Gateway and Lambda.
Very similar to https://ipstack.com/, but we don't want to use an external service as we believe it could be an issue in some jurisdictions to send a non-anonymized IP address to a service we don't control (before getting the user's consent).
Would like to have a simple api https://location.my-site.com that returns the country (for GDPR, cookies, etc purposes).
Now it seems that there is a light Cloudfront behind API Gateway that would produce the header "Cloudfront-Viewer-Country", which would be very simple and achieve what we need. i.e. lambda receives Cloudfront-Viewer-Country and just sends it back.
What we have tried
I have seen solutions such as this one: Build a Geolocation API using AWS Lambda and MaxMind, but I struggle to see why deploying an RDS and maintaining the MaxMind database would make sense for us, if it is already available from Cloudfront-Viewer-Country.
I have seen this question: Accessing cloudfront-viewer-country header in AWS API Gateway using HTTP Proxy?, and tried implementing the answer from Michael - sqlbot. But I cannot seem to access the headers.
I have also tried what is suggested in this post, but I can't seem to access the value of Cloudfront-Viewer-Country either.
What we are doing (in conjunction with 'What we have tried')
To access and check if the header is available I am using the following python lambda function
import json
def lambda_handler(event, context):
response = {
'status': '200',
'statusDescription': 'Found',
'headers': {
'location' : [ {
'event': json.dumps(event)
} ]
}
}
return response
What the problem is
but the event json dump doesn't contain Cloudfront-Viewer-Country.
I suspect I'm doing something wrong but I really can't figure it out. Any pointer would be very much appreciated.
Thank you
I was able to get access to Cloudfront-Viewer-Country by setting a Endpoint Type = Edge optimized.
I could not get it to work with Endpoint Type = Regional or with http api gateway.

Cannot get AWS API Gateway to override response codes - FitBit endpoint verification

I am integrating FitBit with my company's platform and we are switching over from syncing with our own server to sending the data to an AWS Kinesis stream. This requires us to also set up an AWS API Gateway with a POST method to write the data to the stream. I've also set up a GET method on the same resource for the verification process.
Here's the problem I'm facing:
Once I have the API Endpoint properly set up, FitBit provides a verification code and requires a verification process in which it sends a GET request to the endpoint with a ?verify={correctVerificaitonCode} query param and wants a 204 response, and one with a ?verify={incorrectVericationCode} param and wants a 404 response. This would obviously be easy for me to accomplish in our Rails backend, where I'm in control of the code, but on AWS it's a tangled mess with little control.
I have read endless documentation on AWS about Mapping Templates and Integration Response, but no matter what I do, I cannot get the API to respond with anything other than a 200 (when the request is clean and has any ?verify param) or 500 (when I purposefully make a bad request). There is no straightforward answer in the AWS docs about this.
This is the closest I have come to a setup that the docs promise should work, yet it does not:
Using the Integration Response HTTP Status Regex
And with this mapping template
I'm two days in on this and frustrated to my wits' end. Help!
Just in case anyone find this thread in the future and is struggling with the same issue - here is how you verify a FitBit Developer API app with an Amazon Kinesis stream being fed by an AWS API Gateway:
First, set up the POST method of your API - there are AWS guides to this. Select AWS service as the integration type and kinesis as the service, then set up a mapping template for 'application/json' to look like this:
#set($event = $input.body)
#set($data = '{"action":' + $event +', "authorization": "' + $input.params('Authorization') + '", "stage":"' + $context.stage + '"}')
#set($body = $util.base64Encode($data))
{
"Data": "$body",
"PartitionKey": "shard-1",
"StreamName": "gm-fitbit"
}
Once you've done that, create a GET method on the same resource. Set MOCK as the integration type and create the endpoint. Now click on the GET method and visit Method Request. Expand URL Query String Parameters and add verify as a query param. Now, go back to the method and visit Integration Response.
Under the already existing 200 response method, expand it and add an HTTP status regex of 2\d{2} and passthrough handling.
Expand Mapping Templates, and for 'application/json' create this mapping template:
{
#if( $input.params('verify') == "theVerificationCodeProvidedToYouByFitbit" )
#set($context.responseOverride.status = 204)
#else
#set($context.responseOverride.status = 404)
#end
}
That's it! Deploy the API again, head back to Fitbit, and click verify!
There. Now there is officially a guide online to integrating Fitbit with an AWS Kinesis stream, the one I wish I had when struggling with this for 3 days.
Cheers!

API Gateway - Get StatusCode

This should have been such a simple issue and I don't understand why it hasn't come up through all my searching (maybe it's just been a long day).
I have an API Gateway API setup, and I am adding a Body Mapping Template to my Integration Response for a 400* error group: see image -
All I would like to get is the StatusCode of the current response (as this is a 400* group - e.g. 401 / 403 / 404 etc.)
The closest I came was through this site: AWS help documentation and I thought I would be able to use something like $context.statusCode - but no luck.
Am I going crazy, or is this just not something required often?
PS - Making changes to any Lambda functions being called, is not an option.
Thanks
There's currently no mapping template variable in API Gateway dedicated to the integration response status code.
We will certainly add this as a feature request.
At current time you are limited to hardcoding the status code value in your response templates. You would either need to define generic status codes (i.e "4XX") or define integration responses for every status code you want to capture. While this seems tedious, this could be managed relatively easily in a Swagger template.
At current time the only way to see the integration response status code is via CloudWatch Logs.
Thanks,
Ryan / Amazon API Gateway
If you are sending error codes from your server then you can easily map them.
I have done something similar but I have used different trick to do. I used to send my own error entities and codes from server.
You have to map those error entities and error codes coming from server to the response that comes from amazon servers. I will try and explain what I mean by this. Api Gateway doesn't send response coming from your own server to the client automatically. You have to map those responses. For example, map 200 as a SUCESS and response entity will be default, that is whatever coming from server.
Now, we default success response is managed but what about error codes and error entities. You have to map them manually.
There are two ways you can do this,
One is manual, go to your api. Create error entities or models. Map them manually for each response code.
This one uses swaggger,
Solution is to import swagger specification of error entities. Add response templates to the swagger specification and let amazon do their job.
I can help you more with swagger. It depends how you are setting up your api on amazon.
Visit this for amazon extenstions to swagger,
http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html#api-gateway-swagger-extensions-integration-response

Handle Space in AWS API Gateway API URL - I am using Dynamodb Proxy

I have a AWS API Gateway - and using dynamodb to read Data from database, its running good enough if I sent a parameter without Space.
URL Pattern: API_LINK/benchmark_performance/{benchmark}
if {benchmark} is replaced with a String with a space - AWS replies with no/blank data, No Error Reported. if the parameter doesn't have space in it then it sends data correctly. I also tried using JS URI_encoder method and send it but same result
If I test the AWS API End point from AWS console (parameter has Space), then the result is shown properly but the same URL gives no data when called from Browser or angular 2 Application.
Question: What should I do at AWS API Gateway Integration Mapping, that it gives me proper output and handles the space in parameter issue.
Got the answer : http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
I used :
$util.urlDecode() (Decodes an "application/x-www-form-urlencoded" string).
how to use =>
$util.urlDecode($.input.params('yourParameterName'))
in Integration Mapping (section) of API Gateway

AWS API Gateway won't open up

I created a "hello world" lambda function and then deployed it to an end-point using AWS's API Gateway:
All very much basic settings but I was sure to change the security to "open" and while i was told that it could take up for 15 minutes for the domain to resolve I found that even after 30 I was getting the following response from the "open" end-point:
{"message":"Missing Authentication Token"}
Am I missing something obvious? Shouldn't this have been available with what I did?
Note, it was pointed out that this image is of a PUT not a GET. I tried both and both came back errors. Just to check I've run GET and PUT through Postman and get a similar but not identical response:
and then GET ...
When I test the lambda function in the console it runs successfully but running it in the API Gateway it gives me a different articulation of the same error:
Tue Sep 29 20:57:43 UTC 2015 : Execution failed due to configuration error: Invalid permissions on Lambda function
and yet I used the default permissions that the console suggested. The lambda function itself is very basic and can be found here: code
I was having the exact some problem today. Whatever I did didn't work but finally figured out. turns out in order for the changes to take effect, you need to Deploy API.
So first go to Resources and click on Deploy API button. It will ask for a deployment stage. Once deployed I could call my API without any issues.
I know it's been a while since you posted the question, but thought it might come in handy for other people as well.
I had this same issue with a deployed API that was being hit frequently around midday the requests would stop working and fail with { Missing Authentication Token }
My issue was not the URL or a stage that was not deployed but I do know AWS throws that error for both of those reasons.
However I found a command to invalidate the cache of apigateway because in my case I was using a custom domain attached to cloudfront.
aws apigateway flush-stage-cache --rest-api-id 97y41psdkg --stage-name dev
After running this I stopped getting the { Missing Authentication Token }
You need to use "AWS Signature" under the Authorization tab in Postman. See this AWS guide on what to enter into those fields:
http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html
Please use your resource name end of your api URL.
https://***********.execute-api.us-east-1.amazonaws.com/Stag/number
Here number is my resource name