AWS Lambda - getfutureproof/fp_guides_wiki GitHub Wiki
AWS Lambda is a serverless function solution. Perfect for if you have a small action you want to make that would normally go server-side but you don't want to build out and deploy a whole server!
Getting Started
- Go to the Lambda console
- Click
Create function
- Name your function something descriptive and choose your runtime(s) eg. Node.js 14.x
- The default permissions and settings are fine for our purpose today but feel free to take a look!
- Click
Create function
and wait for it...
Dependencies
Creating layers
Rather than 'install' dependencies, you'll need to add layers. Let's walkthrough making a layer for the axios
npm module.
- In your local environment, create a directory for your new layer eg.
mkdir myLayer
andcd
into it - In here,
mkdir nodejs && cd nodejs
- Run
npm init -y
(insidenodejs
folder) - Install your dependency eg.
npm i axios
cd ../
out of your nodejs directory- Zip up the layer directory eg.
zip -r myLayer.zip ./*
Uploading new layers
- Click back to the Lambda Dashboard
- In the left hand menu under
Additional Resources
selectLayers
- Click
Create layer
- Name your layer and click the
Upload
button - Choose your runtimes (make sure you include the one your function runs in!)
- Click
Create
Adding layers to functions
Now you have a new layer you can use it in any function you create in a compatible runtime, you don't need to make duplicate layers
- In your function's console, scroll to the bottom and click
Add a layer
- Select
Custom layers
and choose your layer from the dropdown - Click
Add
The Function
Writing your function
In your function's console Code source
, you can double click on a file name to open it. You'll get a stubbed out lambda handler which is the actual 'lambda function'. This is the entry and exit point of the lambda. The argument it receives will be the trigger event and the return value will be the response object sent back.
Let's walk through making a function that receives a GitHub username, retrieves their data from the GitHub API and returns it back to the original request location.
- Double click the provided
index.js
- At the top of the file import your dependencies eg.
const axios = require('axios');
- Use the (imaginary) event body to retrieve this (imaginary) GitHub username
- Make a call to the GitHub API using the received username
- Extract the data you need and send it back in the response
- Add error handling as appropriate!
Here is a basic example:
const axios = require('axios');
exports.handler = async (event) => {
const body = JSON.parse(event.body)
const username = body.username
let response
try {
const url = `https://api.github.com/users/${username}`
console.log('url is', url)
const { data } = await axios.get(url)
const formatted = {
whereTheyAre: data.location,
whoTheyAre: data.name,
aboutThem: data.bio,
contact: data.email
}
response = {
headers: { "Access-Control-Allow-Origin": "*" },
statusCode: 200,
body: JSON.stringify(formatted),
};
} catch (err) {
response = {
headers: { "Access-Control-Allow-Origin": "*" },
statusCode: err.response.status,
body: JSON.stringify(err.message),
};
}
return response;
};
Add environment variables
If you need to use environment variables eg. for API keys etc. this is a perfect way to get them off your client if you don't want to make a complete back end server.
- In your function's console, go to the
Configuration
tab - From the left hand menu select
Environment variables
- Click
Edit
and add your key value pair eg. key ofMY_API_KEY
, value ofsuper-secret
- Click
Save
- To use your API key in your function, use as a normal env var eg.
process.env.MY_API_KEY
Test
Test your function
If working in the AWS browser console, you can still test your function
- Click
Test
- The
hello-world
event template is fine for testing our function above - Add sample data in the structure you expect (see below for examples to use with our GitHub function)
- Click
Create
- In
Test
select the test event you want to send and check the result! - Note if you are using
JSON.parse
for the event body, remove it for test only eg. above would beconst body = event.body
// event name `ghsuccess`
{
"body": {
"username": "notausernaoeusaeuhasetuh"
}
}
// event name `ghbaduser`
{
"body": {
"username": "notausernaoeusaeuhasetuh"
}
}
Use!
Trigger your function
There are many ways a function can be triggered! We will walk through setting up the ability to call it via an API gateway. This is a great way to do small actions you would normally do server side but for whatever reason you do not want to create an server. Think hiding secret keys in a React app without building out a full Express API for example!
- In your function's
Function overview
, click+ Add trigger
Create API Gateway
- Select ther trigger of your choice, we will use API Gateway
- In the next dropdown select
Create an API
- Select the protocol of your choice, REST is good for us here
- Select the security of your choice,
Open
is fine for us here - The additional settings defaults are fine for our example but check them out to see the options and the note on CORS!
- Click
Add
and you will be redirected to your Triggers list - Expand the
Details
for your API Gateway and copy the API endpoint, you'll need it to call your function!
Enable CORS
To enable CORS on our new REST API:
- Click on the name of your API Gateway in your triggers list, new tab will open with the API settings
- Click the name of your function in the Resources tree, click the
Actions
button and selectEnable CORS
- Select
DEFAULT 4XX
andDEFAULT 5XX
, leave the other settings as they are - Click
Enable CORS and replace existing CORS headers
and confirmYes, replace existing values
- Click
Actions
again andDeploy API
- Select
default
for deployment stage or create a new one and you can add a description if you like! - Click
Deploy
! - Finally, make sure your response objects have the Access-Control-Allow-Origin header (see example code above)
Call your function from your app
Now you can access you function as you would any other API eg.
async function getUserData(username){
const body = JSON.stringify({ username })
const resp = await fetch('https://k44rv0xgu7.execute-api.eu-west-2.amazonaws.com/default/lambda-demo', { method: 'POST', body })
const data = await resp.json()
console.log(data);
}
getUserData('getfutureproof')
Further Reading
Once you are comfortable creating lambdas in the browser AWS console, have a go at deploying a lambda using the AWS CLI
You might have noticed that a POST request felt a bit off for our use above. For a guide on using query params instead of a body, see the official documentation