AWS API Gateway Lambda function works with Postman but not with jquery - amazon-web-services

I have a lambda (node) function that works fine when I invoke it using postman but not when I used jquery $.ajax.
The function is being called from a local html page using javascript/jquery.
I have the 'Allow-Control-Allow-Origin' chrome plugin enabled.
The request passes the same json object using possman and jQuery.
{
"deviceid" : "ZZ-5A-04-A6-XX-YY"
}
I tried the following gateway request mapping templates.
$input.json('$')
When I log the even node object I see the following line
deviceid=ZZ-5A-04-A6-XX-YY
$input.body
I get the error:
Could not parse request body into json: Unrecognized token

Solved this finally.
In addition to using the chrome allow cross origin plugin the data object needs to be send as a string when using jquery ajax.
data: JSON.stringify(hardobj)
Hope someone else does not have to waste a week trying to figure this one out.

Related

503 error when fetching an internal NextJS api with query parameters on AWS Amplify

I am trying to fetch data from a JSON file through NextJS internal API on the client side. But it is always throwing 503 error:
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
I tried to use the GET method with query params in the URL, but it didn't work, then I try the POST method with the query in the body(just to test out), but it also didn't work either.
Here is the code:
const response = await fetch(`/api/search?q=${query}`, {
method: "GET",
headers: {
'Content-Type': 'application/json',
},
})
const res = await response.json()
I have another component that sends some user inputs to save in my DB, and it is working perfectly. (I am really confused why one works but not other given both are equivalent request)
Also, the same app deployed on Vercel is working perfectly. So I think the issue is with Amplify.
Anyone had similar issues with the Next app on Amplify? please help.
most likely you are sending a GET request but you have something in the body. e.g. form-data. this is example in postman.

Slack slash-command through AWS API Gateway to AWS Lambda (Python versus Java)

I am trying to connect a Slack slash-command to an AWS Lambda (through the AWS API Gateway).
I was able to adapt the Hello, World blueprint (written in Python) in the Lambda tutorial section. I set up an API gateway as a trigger, then had Slack POST the slash-command to the API endpoint. I had to manually decode the base64 body, then use parse_qs to convert the query string-like POST body into a dictionary, where I could then access it just fine.
My real Lambda code is currently in Java, but I've started with the java-basic sample app from the Developers Guide. I built the app, uploaded the jar, and confirmed the correct handler was being called. I set up another API gateway and pointed a different Slack slash-command at the new endpoin. It fails.
The log looks like:
java.lang.RuntimeException: An error occurred during JSON parsing
Caused by: java.io.UncheckedIOException: com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
at [Source: (ByteArrayInputStream); line: 1, column: 1]
I'm guessing this means Slack is sending the same query string-like argument in the POST body, and for some reason, something is expecting JSON input, not just text. I don't understand why the Python handler was okay with building up an event dictionary and making the Lambda decode the POST body, whereas the Java handler is never getting called, but is dying before that when attempting to deserialize the POST body, thinking it's JSON.
Both Lambdas and API gateways were set up with the usual defaults, AFAICT.
I solved the problem by switching to using the HandlerStream example. I can then get the "body" from the event, Base64.decodeBase64 it, then unpack the form parameters with UriParameterMap.parse.
I then process the incoming text that came from the Slack slash command and then return a string of JSON that Slack expects.

AWS REST API throws CORS error when invoked from browser works in postman

I configured a REST API in API gateway. It calls a lambda function to return rows. When I tested the API in the AWS console, it works fine. When invoked from the app it throws the following error.
I copied the request as cURL command from the browser and tested from postman, and I see the response in postman. Not sure what I am missing.
Be careful about taking this error too literally. What often happens is that there is a underlying error in the API and it responded with an error message only, and thereby did not send any course headers. So it's not really a course header issue but instead some other error. Check with curl directly and see what's responding with.

Can AWS API Gateway support `application/x-www-form-urlencoded` with body and query string parameters?

Numerous services can accept query string parameters in the URL when a POST request is made with Content-Type: application/x-www-form-urlencoded and other parameters in the body, but it seems AWS API Gateway cannot while also accepting query string parameters.
When I call the AWS API Gateway with a POST Mapping Template for application/x-www-form-urlencoded and query string URL parameters (with a Lambda function), I get the following error:
{
"message":"When Content-Type:application/x-www-form-urlencoded,
URL cannot include query-string parameters (after '?'):
'/prod/webhook?inputType=wootric&outputType=glip&url=...'"
}
Here is an example cURL:
curl -XPOST 'https://{myid}.execute-api.{myregion}.amazonaws.com/prod/webhook? \
inputType=wootric&outputType=glip&url=https://hooks.glip.com/webhook/ \
11112222-3333-4444-5555-666677778888' \
-d "#docs/handlers/wootric/event-example_response-created.txt" \
-H 'Content-Type: application/x-www-form-urlencoded' -v
The specific goal is to get a Wootric webhook event posted to a Lambda function using a URL with query string parameters.
You can get the code here:
https://github.com/grokify/chathooks
The Wootric event body file is here:
https://raw.githubusercontent.com/grokify/chathooks/master/docs/handlers/wootric/event-example_response-created.txt
The GitHub issue is here:
https://github.com/grokify/chathooks/issues/15
The error message seems pretty definitive but I wanted to ask:
Is there a workaround to configure an API Gateway to support both?
Is there a standards-based reason why AWS would not support this or is this just a design decision / limitation?
If there's no solution to this, is there a good lightweight solution other than deploying a hosted server solution like Heroku. Also, do other cloud services support this with their API gateway + cloud functions, like Google?
Some examples showing support for both:
jQuery example: jQuery send GET and POST parameters simultaneously at AJAX request
C# example: Accessing query string variables sent as POST in HttpActionContext
Yes,there is a workaround and the key issue is to set the mapping template that will convert string into json . Very detailed example shown in
API Gateway any content type.
Please set the request property as "Content-Type", "application/json" for your HttpURLConnection like below
connection.setRequestProperty("Content-Type", "application/json");
I had a similar problem, with a 3rd party provider using web hooks. It turns out that my provider is transforming the url path from UPPERCASE to LOWERCASE. Example the endpoint should be apigateway.com/dev/0bscur3dpathRANDOM instead apigateway.com/dev/0bscur3dpathRANDOM. You get the point.
I'm not sure if I got the point in question correctly, but if you want to access the request body that is encoded as application/x-www-form-urlencoded(or anything, actually) in your Lambda function, you should use LAMBDA_PROXY request integration type (aka tick "Use Lambda Proxy integration" checkbox) when creating a method for your resource. Then you can access the request body in event.body field as a plain text in your lambda function and parse it manually.

How to properly call AWS Lambda Function from API Gateway?

I was messing with Lambda recently, and finally got my lambda code running properly. Or at least when I test it using the "Test" from the Lambda page itself, where I can write my JSON by hand.
I need to run this function through API Request, so in my server I was expecting to make a POST request with the JSON data I had in my "Test" before. Turns out it returns me a 502 server error. I`ve tried to test it using the Amazon API Request page, where I can test by choosing the request TYPE, body, queryStrings and so on. And still did not work.
I had a earlier version of this lambda function working with guzzle before. It just required GET parameters, and it was quite simple to setup using guzzle in PHP.
I think this should be very simple and I'm missing something.
Thanks!
info = $guzzle->post('https://my-secret-url.execute-api.us-west-2.amazonaws.com/prod/lambda-function-name', [
'query' =>
[
'out' => 'lambda/piperun.pdf',
'in' => 'invoice,propostas_7_5.pdf'
],
'json' => $this->proposta->getJSONData() //Same JSON from image
]);