Example of using FaunaDB with Netlify functions
This application is using React for the frontend, Netlify Functions for API calls, and FaunaDB as the backing database.
-
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
- Sign up for free FaunaDB account,
- Grab your FaunaDB API key
- Click the Deploy to Netlify Button
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
-
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
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=YourFaunaDBKeyHere
Add 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.json
file{ "scripts": { "bootstrap": "node ./scripts/bootstrap-fauna-database.js" } }
Now we can run the
bootstrap
command to setup our Fauna database in our FaunaDB account.npm run bootstrap
If you login to the [FaunaDB dashboard](https://dashboard.fauna.com] you will see your todo database.
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.
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
Lets rock and roll.
-
Create a
./functions
directory with there# make functions directory mdkir functions
-
Install
netlify-lambda
Netlify 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-dev
To simulate our function endpoints locally, we need to setup a proxy for webpack to use.
In
package.json
add:{ "name": "react-lambda", ... "proxy": { "/.netlify/functions": { "target": "http://localhost:9000", "pathRewrite": { "^/\\.netlify/functions": "" } } } }
This will proxy requests we make to
/.netlify/functions
to our locally running function server at port 9000. -
Add our
start
&build
command to npm scripts inpackage.json
We are going to be using the
npm-run-all
npm module to run our frontend & backend in parallel in the same terminal window.So install it!
npm install npm-run-all --save-dev
About
npm start
The
start:app
command will runreact-scripts start
to run our react appThe
start:server
command will runnetlify-lambda serve functions -c ./webpack.config.js
to run our function code locally. The-c webpack-config
flag lets us set a custom webpack config to fix a module issue with faunaDB module.Running
npm start
in our terminal will runnpm-run-all --parallel start:app start:server
to fire them both up at once.About
npm build
The
build:app
command will runreact-scripts build
to run our react appThe
build:server
command will runnetlify-lambda build functions -c ./webpack.config.js
to run our function code locally.Running
npm run build
in our terminal will runnpm-run-all --parallel build:**
to fire them both up at once.Your
package.json
should 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
faunadb
npm module to call into our todos index in FaunaDB.So install it in the project
npm i faunadb --save
Then create a new function file in
/functions
calledtodos-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) }) }) }
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)
})