Building a REST API with AWS Lambda, Fauna, and Serverless Framework
This post refers to a previous version of FQL.
This post refers to a previous version of FQL (v4). For the most current version of the language, visit our FQL documentation.
This tutorial teaches you how to build a serverless REST API using AWS Lambda and Fauna (as your database). You use the Serverless Framework as your infrastructure as code for this tutorial.
Create a new Serverless project
Create a new serverless project by running the following command to get started.
$ serverless create --template aws-nodejs
Notice that we are using the aws-nodejs template. This scaffolds a lot of code for you, so you don't have to write everything from scratch.
Next, add serverless-fauna
and serverless-dotenv-plugin
as dependencies on your project.
$ npm i severless-fauna serverless-dotenv-plugin --save
Configure Fauna resources
Open the project in your favorite code editor. Open the serverless.yml
file and add the following code.
service: fauna-serverless-v2
frameworkVersion: '3'
# Specify donenv
useDotenv: true
# Add Fauna plugin
plugins:
- serverless-dotenv-plugin
- serverless-fauna
# Define Fauna resources
fauna:
client:
secret: ${env:FAUNA_ROOT_KEY}
domain: ${env:FAUNA_DOMAIN}
collections:
Books:
name: Books
provider:
name: aws
runtime: nodejs12.x
httpApi:
cors: true
You define all the Fauna resources you want to create in the YML file. For instance, in the previous code block, you create a new Book collection.
Next, head over to Fauna and create a new server key for your database. Create a new .env
file at the root of your project. Add the Fauna key and domain as environment variables.
FAUNA_ROOT_KEY='fnA.............'
FAUNA_DOMAIN='db.us.fauna.com'
Configure AWS Lambda
Next, add the Lambda configuration to your YML file. Add the following code snippet to your YML file.
# ...partials of serverless.yml
# ...
provider:
name: aws
runtime: nodejs12.x
httpApi:
cors: true
# Define lambdas
**functions:
book:
handler: handler.book
events:
- httpApi:
path: /books/{id}
method: get
createBook:
handler: handler.createBook
events:
- httpApi:
path: /books
method: post
deleteBook:
handler: handler.deleteBook
events:
- httpApi:
path: /books/{id}
method: delete
updateBook:
handler: handler.updateBook
events:
- httpApi:
path: /books/{id}
method: put**
In the previous code snippet, you create a Lambda function to handle Create, Read and Update and Delete scenarios.
Write Lambda code
Next, write the code for your Lambda functions. You need the faunadb drive to connect to Fauna from your Lambda functions. Install the faunadb package in your project.
$ npm i faunadb --save
Open the handler.js file and add the following code snippet. In the following code snippet, you initialize the Fauna driver. Then you create functions to query and insert data to Fauna.
// handler.js
// import faunadb driver
const faunadb = require('faunadb')
const q = faunadb.query;
// initialize fauna client
const serverClient = new faunadb.Client({
secret: process.env.FAUNA_ROOT_KEY,
domain: process.env.FAUNA_DOMAIN,
});
// Create Book Route
module.exports.createBook = async (event, context, callback) => {
const data = JSON.parse(event.body);
try {
const newBook = await serverClient.query(
q.Create(
q.Collection('Books'),
{ data },
)
)
callback(null, {
statusCode: 201,
body: JSON.stringify(newBook)
});
} catch (error) {
throw new Error(error)
}
}
// Get Book
module.exports.book = async (event, context, callback) => {
try {
const book = await serverClient.query(
q.Get(
q.Ref(q.Collection('Books'),
event.pathParameters.id
)
)
)
callback(null, {
statusCode: 200,
body: JSON.stringify(book)
});
} catch (error) {
throw new Error(error)
}
}
// Delete Book
module.exports.deleteBook = async (event, context, callback) => {
try {
const book = await serverClient.query(
q.Delete(
q.Ref(q.Collection('Posts'),
event.pathParameters.id
)
)
)
callback(null, {
statusCode: 204,
body: JSON.stringify(book)
});
} catch (error) {
throw new Error(error)
}
}
// Update Book
module.exports.updateBook = async (event, context, callback) => {
const data = JSON.parse(event.body);
try {
const book = await serverClient.query(
q.Update(
q.Ref(q.Collection('Books'), event.pathParameters.id),
{ data },
)
)
callback(null, {
statusCode: 201,
body: JSON.stringify(book)
});
} catch (error) {
throw new Error(error)
}
}
To learn more about how the Fauna driver works, head to the official documentation page. The Fauna driver is also available in other languages such as C#, Java, Scala, and Go.
Deploy your stack
Deploy your stack by running the following command.
$ sls deploy
Once everything is deployed your API will be live.
And that’s a wrap. Check out the Fauna official documentation page to learn more about Fauna. Want to learn more about the Serverless Framework? Check out their official documentation page. You can find the complete code in the following git repository.
If you enjoyed our blog, and want to work on systems and challenges related to globally distributed systems, and serverless databases, Fauna is hiring
Subscribe to Fauna's newsletter
Get latest blog posts, development tips & tricks, and latest learning material delivered right to your inbox.