Fauna is an excellent choice for storing data in the cloud, and the fauna NPM package is a full featured adapter around the service. It adapts the Fauna Query Language (FQL) almost directly in JavaScript, but it can be somewhat confusing for developers new to the platform. Thats why I built FaunaService, a simple wrapper around basic CRUD operations for Fauna. The package simplifies these basic operations into simple functions that can be used by any application quickly, without having the learn FQL. In this article, I'll explain how to set up the FaunaService object, give a demo of each function, and end with a sample API written in Express. I'll also assume you have a database & collection already setup. The code shown below will be on a Windows 10 machine with the latest build, but to follow along you should also have the following installed;

  • VSCode (or an IDE of your choice)
  • NodeJS (The latest LTS version)

Fauna is free to start, click here to create an account!

Getting Your API Key

Before we can start coding, you'll need to create an API key for your database. Open your database in Fauna, click on Security in the bottom left, and create a key. I'm going to select the Server option for my role (so as to not give the key too much access), and give the key a name just so I know what its for in the future.

Make sure to note your key now as you wont be able to going forward.

Start Your Project

To start, open a new folder in VSCode and initialize a new project with npm init -y to accept all the defaults. The run npm install @brianmmdev/faunaservice` to install the package and its dependencies.

Now lets start writing some code! Create a file called app.js and import the package. Create a new FaunaService class and pass in your key to initialize it.

CRUD Examples

The service has five distinct functions that are exported, all of which are asynchronous;

  • createRecord(collectionName, data)
  • listRecords(collectionName)
  • getRecordById(collectionName, recordId)
  • updateRecord(collectionName, recordId, updates)
  • deleteRecord(collectionName, recordId)

We'll start by creating a few records just to populate our collection with some data. To create records, simply pass in any JavaScript object and it will be added to the collection. Using the createRecord function also returns what was added into the collection along with the id for that record.

One thing to note about the id field is that it maps directly to the refId inside Fauna. The package simply flattens the object returned directly from the Fauna operation to make it easier to work with.

Now to see all of the data in our collection, we can use the listRecords function like so. The objects will be flattened as above and be returned as an array.

To fetch a single record, use the getRecordById function with the collection name and Id of the object. I'm going to grab an Id from another record directly from the Fauna dashboard.

Now let's say we've completed this specific task and want to mark it as such, we can use the updateRecord function to do so. This function will only update the fields that are passed in, so no need to include the name of the task as well. As with createRecord the data will be returned if needed;

And finally, we can delete records with deleteRecord. By reviewing the Fauna dashboard, we can see the record is indeed gone.

Example API

Before I close it out, I want to give an example of what an API built with Express might look like. The source code for this is available at https://github.com/bmorrisondev/faunaservice-demo.

const FaunaService = require("@brianmmdev/faunaservice")
const bodyParser = require('body-parser')
const express = require('express')
const app = express()

app.use(bodyParser.json())

const service = new FaunaService("your_fauna_key")

// Get all tasks
app.get("/tasks", async (req, res) => {
  let records = await service.listRecords("TaskData")
  res.json(records)
})

// Get a single task by id
app.get("/tasks/:id", async (req, res) => {
  let record = await service.getRecordById("TaskData", req.params.id)
  res.json(record)
})

// Create a task
app.post("/tasks", async (req, res) => {
  let data = req.body
  let created = await service.createRecord("TaskData", data)
  res.json(created)
})

// Update a task
app.put("/tasks/:id", async (req, res) => {
  let updates = req.body
  let updated = await service.updateRecord("TaskData", req.params.id, updates)
  res.json(updated)
})

// Delete a task
app.delete("/tasks/:id", async (req, res) => {
  await service.deleteRecord("TaskData", req.params.id)
  res.status(200).send()
})

app.listen(3000, () => console.log("API is running!"))

Conclusion

While this package doesn't cover the vast capabilities of Fauna, it does indeed give new developers, as well as those looking to create quick demos, an edge over having to learn a new query language by simplifying the most basic operations down to a single line of code! If you are interested in contributing, the package is open source and located at https://github.com/bmorrisondev/faunaservice.