AWS Lambda + API Gateway Flashcards
Explain how to make a lambda function in AWS Lambda
You will take the backend function and place it in a separate folder where you can install the necessary dependencies. After installing the dependencies, zip the folder with the .js file and node_modules.
Go to AWS Lambda and give the function a name. Upload the zip folder as the functionality. You will probably need to drag and drop all the files from the folder you created into the new root folder. Don’t know why it doesn’t take care of this automatically.
Keep in mind the .js file will have a separate format that will work with Lambda. This is an example:
const nodemailer = require(‘nodemailer’);
exports.handler = async (event) => {
try {
// Parse the request body from the event
const { name, email, message } = JSON.parse(event.body);
let transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: 'thomas@hartecho.com', pass: 'cjyo osuo ebfj knvz', }, }); let mailOptions = { from: 'thomas@hartecho.com', to: 'thomas@hartecho.com', subject: 'New Contact Submission', text: `${name} just sent a submission!\n\nEmail: ${email}\n\nMessage:\n\n${message}`, }; await transporter.sendMail(mailOptions); // Return success response with CORS headers return { statusCode: 200, headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", // Allow requests from any origin "Access-Control-Allow-Methods": "OPTIONS, POST", // Allow OPTIONS and POST methods "Access-Control-Allow-Headers": "Content-Type" // Allow Content-Type header }, body: JSON.stringify({ message: 'Email sent successfully' }), }; } catch (error) { console.error('Error sending email', error); // Return error response with CORS headers return { statusCode: 500, headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", // Allow requests from any origin "Access-Control-Allow-Methods": "OPTIONS, POST", // Allow OPTIONS and POST methods "Access-Control-Allow-Headers": "Content-Type" // Allow Content-Type header }, body: JSON.stringify({ error: 'Failed to send email' }), }; } };
Note: These CORS headers are required to work with API Gateway.
You need to save any changes you make to the files and click deploy for the changes to take effect, even for testing.
You can then test your function using a test formatted like this:
{
“body”: “{"name":"Test Name","email":"test@example.com","message":"Hello, this is a test."}”
}
NOTE: There is a timeout option on the lambda function that defaults to 3 seconds. If it takes longer than that, you’ll get a bad gateway error, so turn this up if needed. Its under configuration, general configuration.
How do you integrate an AWS Lambda function into API Gateway?
Create a new REST API, select “New API” and enter an appropriate name.
In the Resources tab, click “Create resource”. Name it a particular path and check the box so it automatically creates an “Options” method.
Next click the path you just created, and there should be a “methods” section. Create a new method and make it a lambda function integration with the appropriate method type. Check Lambda proxy integration and choose the lambda function that you want this api to call. Create method.
Now for CORS, you first want to make sure your lambda function returns the appropriate headers, which is shown in the other card. Next click the path on the resources tab, which should reveal an “Enable CORS” button in the section to the right. I check both default 4XX and 5XX (not sure the difference). They seem to have defaults for Access-Control-Allow-Headers and Origin. I believe that’s all you need. Click save.
Now when you click on OPTIONS or POST (or whichever method you’re setting up) in the resources section, you should be able to see the response headers in method responses. OPTIONS should have Headers, Methods, and Origin while POST should have just Origin.
Deploy this API into a new stage (call it whatever), and this should then reveal the url you should copy into your web application. Remember that this path is not complete. You need to add the path that you specified in the resources section. So it should be /stageName/pathYouMade in your web application.
Also make sure the method, headers, and body are correctly defined or the preflight so and so (OPTIONS method) will come back with a CORS error because it didnt return with a 200 status. Here is an example of what works:
const response = await fetch(
“https://jf32m0961a.execute-api.us-east-2.amazonaws.com/first/send-custom-email”,
{
method: “POST”,
headers: {
“Content-Type”: “application/json”,
},
body: JSON.stringify({
to: formData.value.email,
from: “thomas@hartecho.com”,
message:
“Your contact submission was successful! We will get back to your shortly. Here is a preview of the message you sent: \n\n” +
formData.value.message,
company: “Buzzed Honey”,
}),
}
);
Without the JSON.stringify around the body object, for example, it caused the error where the preflight call didn’t return 200. This may change depending on how you deal with the data, but sometimes its client side info that’s causing issues on the server.
You can see if there are errors in the lambda function through cloudwatch and test within the console. I believe you need to manually turn on cloudwatch for API Gateway, which requires giving correct permissions or something, but I’ve been able to figure it out without ever enabling that.
What will cause CORS issues with this whole process?
Any return statement in the Lambda function has to have the CORS headers:
return {
statusCode: 200,
headers: {
“Content-Type”: “application/json”,
“Access-Control-Allow-Origin”: “*”, // Allow requests from any origin
“Access-Control-Allow-Methods”: “OPTIONS, POST”, // Allow OPTIONS and POST methods
“Access-Control-Allow-Headers”: “Content-Type” // Allow Content-Type header
},
body: JSON.stringify({ message: ‘Email sent successfully’ }),
};
This goes for ANY return statement, error or not.
Then in API Gateway, make sure the OPTIONS method allows headers, methods, origins, and the POST method allows origin. If you go to the root of those methods there is a button that says enable CORS, and it should do it for you.
How do you error check Lambda functions?
There is a monitor tab on each Lambda function that will take you to the cloudwatch logs that match that function. Put console.log statements in the index.js file of the Lambda function, hit deploy so they go through, and the outputs will be in the cloudwatch logs.