11 KiB
Netlify + FaunaDB 
Example of using FaunaDB with Netlify functions
About this application
This application is using React for the frontend, Netlify Functions for API calls, and FaunaDB as the backing database.
Setup & Run Locally
-
Clone down the repository
git clone git@github.com:netlify/netlify-faunadb-example.git -
Install the dependencies
npm install -
Bootstrap your FaunaDB table
npm run bootstrap -
Set your Fauna API key value in your terminal enviroment
You can create faunaDB keys here: https://dashboard.fauna.com/db/keys
In your terminal run the following command:
export FAUNADB_SECRET=YourFaunaDBKeyHere -
Run project locally
npm start
TLDR; Quick Deploy
- Sign up for free FaunaDB account,
- Grab your FaunaDB API key
- Click the Deploy to Netlify Button
Tutorial
Lets run through how to create Netlify functions and connect them to our frontend application.
- Create React app
- Setup FaunaDB
- Create a function
- Connect the function to the frontend app
1. Create React app
-
Install create react app
npm install create-react-app -g -
Create the react app!
create-react-app my-app -
The react app is now setup!
# change directories into my-app cd my-app # start the app npm start
2. Setup FaunaDB
First things first, we need to setup a FaunaDB account and get our API key we will use to scaffold out our todos database.
Head over to https://app.fauna.com/sign-up to create a free Fauna Account.
-
Sign up
-
Create a key
-
Name your key and create
-
Copy this API key for later use, or Deploy to Netlify Button and plugin this API key.
-
Create your FaunaDB database
Set the FaunaDB API key locally in your terminal
# on mac export FAUNADB_SECRET=YourFaunaDBKeyHere # on windows set FAUNADB_SECRET=YourFaunaDBKeyHereAdd the /scripts/bootstrap-fauna-database.js to the root directory of the project. This is an idempotent script that you can run 1 million times and have the same result (one todos database)
Next up, add the bootstrap command to npm scripts in your
package.jsonfile{ "scripts": { "bootstrap": "node ./scripts/bootstrap-fauna-database.js" } }Now we can run the
bootstrapcommand to setup our Fauna database in our FaunaDB account.npm run bootstrapIf you login to the [FaunaDB dashboard](https://dashboard.fauna.com] you will see your todo database.
3. Create a function
Now, lets create a function for our app and wire that up to run locally.
The functions in our project are going to live in a /functions folder. You can set this to whatever you'd like but we like the /functions convention.
Anatomy of a Lambda function
All AWS Lambda functions have the following signature:
exports.handler = (event, context, callback) => {
// event has informatiom about the path, body, headers etc of the request
console.log('event', event)
// context has information about the lambda environment and user details
console.log('context', context)
// The callback ends the execution of the function and returns a reponse back to the caller
return callback(null, {
statusCode: 200,
body: JSON.stringify({
data: '⊂◉‿◉つ'
})
})
}
We are going to use the faunadb npm package to connect to our Fauna Database and create an item
Setup
Lets rock and roll.
-
Create a
./functionsdirectory with there# make functions directory mdkir functions -
Install
netlify-lambdaNetlify lambda is a tool for locally emulating the serverless function for development and for bundling our serverless function with third party npm modules (if we are using those)
npm i netlify-lambda --save-devTo simulate our function endpoints locally, we need to setup a proxy for webpack to use.
In
package.jsonadd:{ "name": "react-lambda", ... "proxy": { "/.netlify/functions": { "target": "http://localhost:9000", "pathRewrite": { "^/\\.netlify/functions": "" } } } }This will proxy requests we make to
/.netlify/functionsto our locally running function server at port 9000. -
Add our
start&buildcommand to npm scripts inpackage.jsonWe are going to be using the
npm-run-allnpm module to run our frontend & backend in parallel in the same terminal window.So install it!
npm install npm-run-all --save-devAbout
npm startThe
start:appcommand will runreact-scripts startto run our react appThe
start:servercommand will runnetlify-lambda serve functions -c ./webpack.config.jsto run our function code locally. The-c webpack-configflag lets us set a custom webpack config to fix a module issue with faunaDB module.Running
npm startin our terminal will runnpm-run-all --parallel start:app start:serverto fire them both up at once.About
npm buildThe
build:appcommand will runreact-scripts buildto run our react appThe
build:servercommand will runnetlify-lambda build functions -c ./webpack.config.jsto run our function code locally.Running
npm run buildin our terminal will runnpm-run-all --parallel build:**to fire them both up at once.Your
package.jsonshould look like{ "name": "netlify-fauna", "scripts": { "👇 ABOUT-bootstrap-command": "💡 scaffold and setup FaunaDB #", "bootstrap": "node ./scripts/bootstrap-fauna-database.js", "👇 ABOUT-start-command": "💡 start the app and server #", "start": "npm-run-all --parallel start:app start:server", "start:app": "react-scripts start", "start:server": "netlify-lambda serve functions -c ./webpack.config.js", "👇 ABOUT-prebuild-command": "💡 before 'build' runs, run the 'bootstrap' command #", "prebuild": "echo 'setup faunaDB' && npm run bootstrap", "👇 ABOUT-build-command": "💡 build the react app and the serverless functions #", "build": "npm-run-all --parallel build:**", "build:app": "react-scripts build", "build:functions": "netlify-lambda build functions -c ./webpack.config.js", }, "dependencies": { "faunadb": "^0.2.2", "react": "^16.4.0", "react-dom": "^16.4.0", "react-scripts": "1.1.4" }, "devDependencies": { "netlify-lambda": "^0.4.0", "npm-run-all": "^4.1.3" }, "proxy": { "/.netlify/functions": { "target": "http://localhost:9000", "pathRewrite": { "^/\\.netlify/functions": "" } } } } -
Install FaunaDB and write the create function
We are going to be using the
faunadbnpm module to call into our todos index in FaunaDB.So install it in the project
npm i faunadb --saveThen create a new function file in
/functionscalledtodos-create.js/* Import faunaDB sdk */ import faunadb from 'faunadb' const q = faunadb.query const client = new faunadb.Client({ secret: process.env.FAUNADB_SECRET }) exports.handler = (event, context, callback) => { const data = JSON.parse(event.body) console.log("Function `todo-create` invoked", data) const todoItem = { data: data } /* construct the fauna query */ return client.query(q.Create(q.Ref("classes/todos"), todoItem)) .then((response) => { console.log("success", response) return callback(null, { statusCode: 200, body: JSON.stringify(response) }) }).catch((error) => { console.log("error", error) return callback(null, { statusCode: 400, body: JSON.stringify(error) }) }) }
3. Connect the function to the frontend app
Inside of your react app. You can now wire up the /.netlify/functions/todos-create endpoint to an AJAX request
// Function using fetch to POST to our API endpoint
function createTodo(data) {
console.log('run new create function')
return fetch('/.netlify/functions/todos-create', {
body: JSON.stringify(data),
method: 'POST'
}).then(response => {
return response.json()
})
}
// Todo data
const myTodo = {
title: 'My todo title',
completed: false,
}
// create it!
createTodo(myTodo).then(() => {
}).catch((error) => {
console.log('API error', error)
})





