How do you add JSON data to an HTML AWS lambda response body? - amazon-web-services

I've run into some trouble with a site I am building. It used AWS lambda functions. I am building and deploying on AWS CodeStar.
The site strips the URL parameter (e.g. /BTC), sends that to external API endpoint, which returns some JSON data. I can display the entire JSON response using body: JSON.stringify(response), so it is definitely coming through from the API. However, I would like to the JSON values to HTML markup before sending back to the client. Yet, when I do something like var html = '<h1>JSON.stringify(response['DISPLAY']['BTC']['USD']['MARKET'])</h1>';. I receive an Internal Server Error - Malformed Request.
I can't figure this out. I'm fairly new to the world of AWS, so may be overlooking something, I've looked around in the docs and can't seem to find anything related to this.
Also, when I had the JSON.stringify output displaying on the webpage. If I re-parsed this in the browser console, response['DISPLAY']['BTC']['USD']['MARKET'] returned a value - so I am fairly sure the syntax for the payload data is correct.
exports.get = function(event, context) {
var ticker = event.pathParameters.currency;
rp(`https://min-api.cryptocompare.com/data/pricemultifull?fsyms=${ticker}&tsyms=USD`)
.then(function (response) {
var html = `<h1>${JSON.stringify(response['DISPLAY']['BTC']['USD']['MARKET'])}</h1>`;
context.succeed({
statusCode: 200,
body: html,
headers: {'Content-Type': 'text/html'}
});
})
.catch(function (err) {
console.log('error: ', err);
});
};
Any help would be appreciated! Happy to provide more info if required.

This is caused by a combination of a couple of things, as far as I can tell:
Within your .catch block you are not calling context.error. In other words, if there's an error in your lambda function, the lambda function never signals that it's finished executing properly to the invoker. API gateway throws up its hands in despair and spits out a 502 error.
response is a string, so when you try to access its properties, you cause an exception and end up in your .catch block. First you need to JSON.parse(response)
Here's a helpful note: whenever you call console.log, the log output can be found in CloudWatch > Logs > /aws/lambda/<your-lambda-name>. This can be useful for figuring out why/where things are breaking.

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.

Access cookie in pre request script in postman v8

I am trying to get the cookies in the pre request script to chain it with other request which returns as empty array using the example below.
With the latest release of postman v8, the cookies object cannot be fetched using the pm.sendRequest which would otherwise work in postman versions less than 8.
pm.sendRequest(url, function (err, response, { cookies }) {
console.log(cookies.all());
});
I think you might need something like this to see the cookies:
pm.sendRequest("https://postman-echo.com/get", function (err, response, options) {
console.log(options.cookies.members);
});
From here you could loop through the members array to get what you need.

AWS Documentation: How is Lambda's response var used in API Gateway?

I am reading this AWS blog post to learn how to make my static website's form POST data to API Gateway and Lambda.
Most of it makes sense to me, but the Lambda code provided contains this unused variable:
var response = {
"isBase64Encoded": false,
"headers": { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': 'example.com'},
"statusCode": 200,
"body": "{\"result\": \"Success.\"}"
};
I believe this is needed (based on this AWS documentation), but is it used automatically? Or is the Lambda missing some vital code? For example:
callback(null, response)
Side note: In the blog post, the integration set up is not the lambda proxy one, but rather lambda custom integration - https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-custom-integrations.html
To the question: I am pretty sure that the post contains a typo in context.done(err, null); which should have been context.done(err, response);
However as a result this is not an error, as the custom lambda integration response template is just passing through the empty data and the method response is set to 200 with an empty body.
The response object you are referring to needs to be returned back to the client with the structure provides. The code that you are referencing in the AWS article isn't sending any responses back to the client and that is why you are not seeing the response variable implemented anywhere. To complete the handler function you would return that response variable and transforming the body property to what message you intend to send back to your client. Without this return structure, you will get a 502 error on the client.

How to return nothing in AWS API Gateway?

Sorry for this dumb question, but I tried everything.
I have a AWS API Gateway from a Lambda function that I need to return only HTTP Code 200 with no body. If the lambda returns a empty string, the body shows "" (2 quotation marks). If the lambda returns null, the body shows the word null.
What is the catch? How to return a empty body?
For information, I am using a Slack dash command to call the API. So the call returns a HTTP 200 OK, and the result is sent by POST in a response url; so processing can be done after the HTTP result, in order to avoid timeout problems.
If you are using the "lambda proxy integration" in the "integration request" section (see attached screenshot), you can simply return an empty string through the following structure.
module.exports.hello = (event, context, callback) => {
const response = {
statusCode: 200,
body: ''
};
callback(null, response);
};
I experienced exact the same issue. Lambda Proxy Integration didn't work for me. (Lambda didn't received the request from API Gateway. I think the Proxy disabled Integrated Request > Mapping Template, which transforms slack's application/x-www-form-urlencoded into JSON that Lambda can read.)
Instead, I got another resolution: using Integrated Response. Selected 200 and added Mapping Template then fill in the following code:
#set($inputRoot = $input.path('$'))
After saving and deploying the API (Be sure to return null in the Lambda Function), I got the problem solved. (In my case, I wanted to hide the slash command the user typed in and only show the results.)
I've referenced this article: https://medium.com/#farski/learn-aws-api-gateway-with-the-slack-police-ca8d636e9fc0

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
]);