Skip to main content

Use TakeShape with AWS Lambda

TakeShape and AWS Lambda are a powerful combination for the jamstack developer hoping to abstract away their backend!

This guide will walk you through integrating TakeShape into an AWS Lambda function that you can call from any frontend application! In this case, we'll be using React.

Our goal is to pull a list of products from a TakeShape API and render them to a webpage after calling an AWS Lambda function. If you don't have a project with Ecommerce data, you can use our Shape Shop starter project.

Let's jump in!

NOTE

If you'd rather jump right in, you can check out our AWS Lambda starter repo! It's a repo containing the project we're going to build in this guide.

Connecting your TakeShape project

First, you'll need a TakeShape project! Follow our guide on creating a TakeShape project to get started.

Next, you'll need your project's API key and API endpoint to connect your project to AWS Lambda.

Navigate to your TakeShape project's dashboard. Your API Endpoint will be in the "Useful snippets" section under the Home tab of your project dashboard. Just scroll to the bottom of the page and look at the left side.

To generate an API key, follow our guide on the subject here.

Once you have all the necessary information, it's time to create your frontened app!

Creating your React app

You can use any frontend framework for this project, but for the sake of simplicity we'll use React.

Navigate to a folder where you'd like to store your project, and open up your terminal. Create a React app:

npx create-react-app takeshape-lambda-example

Now open this new project directory in your favorite IDE, or navigate to it in your terminal.

You're all set! Time to configure your AWS Lambda Endpoint!

Configuring your AWS Lambda Endpoint

Your AWS Lambda Endpoint is the endpoint you can make a request to in order to execute your lambda function. Think of it as an API endoint that AWS sets up for you, with minimal code needed on your end!

Setting up your endpoint requires a few things to be established:

  1. You have an AWS account. Sign up for one here.

  2. You have an IAM user account with programmatic access to any endpoints you create. Read the guide to setting up an IAM user here.

Be sure to save your access key ID and secret access key when creating an IAM user!

With those initial steps out of the way, let's get started!

Setting up Serverless framework

Though you can configure your lambda endpoint with the AWS CLI, it's much simpler to use the Serverless CLI framework. Back in your local machine's terminal, run the following command to install it:

npm install -g serverless

Now it'll be much easier to manage and deploy changes to your AWS account!

Change directories into your frontend app in the terminal.

Now add your IAM user's credentials to serverless:

serverless config credentials --provider aws --key YOUR-KEY-HERE --secret YOUR-SECRET-HERE -o

Serverless makes it easy to set up an AWS lambda template once everything is configured. Use the following command to create a folder for your lambda template inside your project's root directory:

serverless create --template aws-nodejs --path aws-takeshape

Now you have a folder called aws-takeshape in the root directory of your project!

If you check its contents, you'll find a handler.js file, which is where your functions will live. By default, this handler.js module is exporting a method called hello. Rename it to getProductList. The file should now look like this:

handler.js
'use strict';

module.exports.getProductList = async (event) => {
return {
statusCode: 200,
body: JSON.stringify(
{
message: 'Go Serverless v1.0! Your function executed successfully!',
input: event,
},
null,
2
),
};

// Use this code if you don't use the http event with the LAMBDA-PROXY integration
// return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};

You can test it out locally by changing directories into this folder and running the following command in your terminal:

serverless invoke local --function getProductList

You should see the status code and body you entered in the function above, printed out in the console.

There's also a serverless.yml file which you can use to configure your serverless setup. Open that file and look for functions. You should find a section of the file that looks like this:

serverless.yml
functions:
hello:
handler: handler.hello

Go ahead and swap out the word hello for getProductList. Now that section of the file should look like this:

serverless.yml
functions:
getProductList:
handler: handler.getProductList

One thing we'll need to add is an event, which is a property you can add to a serverless.yml file to generate an API endpoint for a function you want to deploy. Add the following code to this section of the file, so that it looks like this:

serverless.yml
functions:
getProductList:
handler: handler.getProductList
events:
- http:
path: productlist
method: get

In the above code, we set the path to be productlist, but you're free to make the path whatever you want!

And one last thing: Environment variables!

You can't make a request to your TakeShape project's API if you don't have the endpoint and key! After adding events to your yaml file, you need to add the environment property and set your variables as shown below:

serverless.yml
functions:
getProductList:
handler: handler.getProductList
events:
- http:
path: productlist
method: get
environment:
TAKESHAPE_API_KEY: ${env:TAKESHAPE_API_KEY}
TAKESHAPE_ENDPOINT: ${env:TAKESHAPE_ENDPOINT}

You'll then need to create a .env file in the aws-takeshape folder, which should look like this:

.env
TAKESHAPE_API_KEY=Your-Key-Here

TAKESHAPE_ENDPOINT=Your-Endpoint-Here

To learn where to get your TakeShape project's API Endpoint and API Key, check out this section on connecting your project above!

We can easily deploy this function now, but first let's make sure we're fetching the data we need from AWS. Go back to aws-takeshape/handler.js.

You'll need to create a POST request to your TakeShape API endpoint in the handler module, then forward that data in the body of the response your handler sends. Whatever frontend application calls the endpoint should always get that data.

To make this POST request, we have to do a few things. First, install Axios for your lambda function, which is a node library that simplifies http requests.

Change directories into the serverless service folder:

cd aws-takeshape

Then initialize npm so you can use node packages in your lambda function!

npm init -y

Now you're ready to install axios:

npm i axios

You'll then need to edit the .npmignore file in your aws-takeshape directory to remove node_modules and any instances of .env that appear there. The file should look like this:

.npmignore
# package directories
jspm_packages

# Serverless directories
.serverless

With that file configured properly, your npm packages will be uploaded along with your code, which means axios will be able to make requests.

Finally, it's time to write the function!

Here's how your handler.js file should look:

handler.js
const axios = require('axios');

module.exports.getProductList = async (event) => {
try{
const result = await axios.post(
process.env.TAKESHAPE_ENDPOINT,
{
query: `query {
getProductList{
items{
price
name
_id
image{
sourceUrl
}
}
}
}
`
},
{
headers: {
'Authorization': `Bearer ${process.env.TAKESHAPE_API_KEY}`
}
});

return {
statusCode: 200,
body: JSON.stringify({
products: result.data.data.getProductList.items
}),
};
} catch (err) {

return {
statusCode: 500,
body: JSON.stringify({
message: `Failed to fetch data from TakeShape! ${err}`
}),
};
}
};

As you can see in the above handler module, we're fetching a list of products from TakeShape, then returning that list in an HTTP response if successful; if unsuccessful, we're returning an error message and a 500 status code.

That's all we need for a simple fundamental setup!

Now all you have to do is deploy the function, which takes no time at all!

Change directories into the serverless service folder, which in this case is called aws-takeshape

cd aws-takeshape

Run the deploy command:

serverless deploy

The process for deploying your function to AWS may take some time, but when it's done you should see a list of data about your function in the console. It should list things like the service name, region, stack, api keys, and of course the endpoint you need to hit to execute the function!

Your endpoint will be listed under endpoints, where it says GET.

Copy the endpoint, and you're ready to fetch this data on the frontend!

Calling your AWS Lambda function from the frontend

Now for the easy part! You need to fetch your product list from your AWS endpoint and display it with React. You can check out our guide on implementing TakeShape with React if you'd like an in-depth look at the process.

For this guide, we'll move somewhat quickly through an explanation of the code.

In your React app, change directories back to the root directory of your project:

cd ..

Now it's just a matter of fetching the data in your src/App.js component! Just remember that if you used the code above for your handler.js, your lambda function will return an array rather than an object.

Create a .env file and add your AWS endpoint to it like so:

.env
REACT_APP_AWS_ENDPOINT=Your-Endpoint-Here

And here's what your App.js might look like:

App.js
import { useState, useEffect } from 'react';

function App() {

const [productList, setProductList] = useState(null);

useEffect(() => {
(async ()=>{
try {
const result = await fetch(process.env.REACT_APP_AWS_ENDPOINT);
const resultJSON = await result.json();
setProductList(resultJSON.products);
console.log(resultJSON);
} catch (err){
console.log('Failed to get data from AWS lambda function', err);
}
})();
}, [])

return (
<main style={{width:'50%',margin:'auto', display:'flex', flexDirection:'column'}}>
{productList && productList.map(product=>(
<div key={product._id} style={{display:'flex', flexDirection:'column'}}>
<img alt={product.name} style={{maxWidth:'800px'}} src={product.image.sourceUrl}></img>
<h2>{product.name}</h2>
<b>{product.price}</b>
</div>
))}
</main>
);
}

export default App;

In the above code, you're simply fetching your product list from your AWS endpoint and displaying it in a series of divs with React.

Run the project with:

npm run start

Here's what the page should look like:

Still need help? Get in touch with us!

Other ways to use AWS Lambda with TakeShape

Check out our guide on connecting AWS Lambda to your TakeShape project as service.

You can also see our guide for using AWS Lambda as an API Resolver.