A beginner’s guide to Fauna

After having a hard time trying to grasp Fauna and serverless databases, I came up with the idea of demystifying what I have learned and the quickest way to get up and running with the Fauna.

Who is this for?

Those new to serverless databas…


This content originally appeared on DEV Community and was authored by samaby

After having a hard time trying to grasp Fauna and serverless databases, I came up with the idea of demystifying what I have learned and the quickest way to get up and running with the Fauna.

Who is this for?

Those new to serverless databases who would like to try out Fauna to use in a project. You need basic programming knowledge to walk you through the lesson.

Concept

In the tutorial, we will demonstrate how to model a basic Twitter social graph and access it on the web using Node.js, explaining how Fauna works as we implement it.

Fauna is a next-generation cloud database that combines the simplicity of NoSQL, without sacrificing the ability to model complex relationships. It’s completely serverless, fast, ACID-compliant, and has a generous free tier for small apps — basically everything you could possibly want in a fully-managed database.
The following lesson demonstrates how to model a basic Twitter-inspired social graph with Fauna and access it on the web with Node.js. It will introduce you to Fauna Query Language (FQL) and common patterns for reading and writing to the database.

Initial setup

Start by creating a Node project, then install the Fauna JS package and Express.

npm init -y

npm install faunadb express

Initialize Fauna

Create a server key from the Fauna security tab. Initialize the client with your server key, then import the FQL functions required for this demo.

// src/index.js 

const faunadb = require('faunadb');
const client = new faunadb.Client({ secret: 'YOUR-KEY' })

// FQL functions
const {
    Ref,
    Paginate,
    Get,
    Match,
    Select,
    Index,
    Create,
    Collection,
    Join,
    Call,
    Function: Fn,
} = faunadb.query;

Initialize Express

We’ll use Express to serve the API.

// src/index.js 
const app = require('express')();

app.listen(5000, () => console.log('API on http://localhost:5000'))

At this point, I would recommend using an API client like Insomnia to make requests to your API on http://localhost:5000

Database structure

The database contains three collections - users, tweets, and relationships. Create these collections from the Fauna dashboard.

Users and tweets

In the following section, we will create a variety of API endpoints for reading and writing tweets to Fauna. A user has many tweets, a tweet belongs to a user.

Create a tweet

First, go to the Fauna dashboard, and create a document with your name as the username. Our goal is to associate many tweets to this user account.
Next, create an index to search for a user based on the username.

A one-to-many relationship can be established by retrieving the user document Ref, then using it as the data with the Create function.

// src/index.js 
app.post('/tweet', async (req, res) => {

    const data = {
        user: Select('ref', Get(Match(Index('users_by_name'), 'fireship_dev'))),
        text: 'Hello world!'
    }

    const doc = await client.query(
        Create(
            Collection('tweets'),
            { data }
        )
    )

    res.send(doc)
});

Read a tweet by ID

Reading a document by its ID does not require an index. Use Get to read a single document by pointing to its collection and reference ID.

// src/index.js 
app.get('/tweet/:id', async (req, res) => {

    const doc = await client.query(
        Get(
            Ref(
                Collection('tweets'),
                req.params.id
            )
        )
    )

    res.send(doc)

});

Query a user’s tweets

Reading multiple tweet documents by the user attribute requires an index. Create an index named tweets_by_user with a search term of user.
The Paginate function will return all documents that match the query.

// src/index.js
app.get('/tweet', async (req, res) => {

    const docs = await client.query(
        Paginate(
            Match(
                Index('tweets_by_user'), 
                Select('ref', Get(Match(Index('users_by_name'), 'fireship_dev')))
            )
        )
    )

    res.send(docs)
});

Fauna functions

The code presented above duplicates the following line of FQL several times:

Select('ref', Get(Match(Index('users_by_name'), '<username>')))

Fauna Functions provide a way to extract this logic to the cloud to reduce duplication and improve maintainability.

Create a function

Extract the duplicated code to a function from the Fauna dashboard. The function accepts the username string as an argument and returns the full user document reference.

Call a function

Use Call to execute this function in a query. For example, we can refactor the previous example like so:

// src/index.js
const {
    Call,
    Function: Fn,
} = faunadb.query;

app.get('/tweet', async (req, res) => {

    const docs = await client.query(
        Paginate(
            Match(
                Index('tweets_by_user'), 
                Call(Fn("getUser"), '<username>v')
            )
        )
    )

    res.send(docs)
});

User-to-user relationships

The following section models a social graph where users can follow other users, then query a feed of their tweets.

Create a relationship

A relationship document contains two user references — the follower and followee.

// src/index.js
app.post('/relationship', async (req, res) => {


    const data = {
        follower: Call(Fn("getUser"), 'bob'),
        followee: Call(Fn("getUser"), '<username>')
    }
    const doc = await client.query(
        Create(
            Collection('relationships'),
            { data }
        )
    )

    res.send(doc)
});

Query a feed of tweets

After establishing a relationship, you likely want to query tweets from followed users — this will require a Join.
Create an index named followees_by_follower with a search term of follower and a value of follower.
The Paginate function will return all followed users, then Join will match the user references to the tweets_by_user index.

src/index.js
app.get('/feed', async (req, res) => {
    const docs = await client.query(
        Paginate(
            Join(
                Match(
                    Index('followees_by_follower'),
                    Call(Fn("getUser"), 'bob')
                ),
                Index('tweets_by_user'),
            )
        )
    )

    res.send(docs)
});

Conclusion

In the tutorial, we demonstrated how to model a basic Twitter social graph and access it on the web using Node.js, explaining how Fauna works as we implemented it.

Written in connection with the Write with Fauna Program.


This content originally appeared on DEV Community and was authored by samaby


Print Share Comment Cite Upload Translate Updates
APA

samaby | Sciencx (2021-09-13T16:42:41+00:00) A beginner’s guide to Fauna. Retrieved from https://www.scien.cx/2021/09/13/a-beginners-guide-to-fauna/

MLA
" » A beginner’s guide to Fauna." samaby | Sciencx - Monday September 13, 2021, https://www.scien.cx/2021/09/13/a-beginners-guide-to-fauna/
HARVARD
samaby | Sciencx Monday September 13, 2021 » A beginner’s guide to Fauna., viewed ,<https://www.scien.cx/2021/09/13/a-beginners-guide-to-fauna/>
VANCOUVER
samaby | Sciencx - » A beginner’s guide to Fauna. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/13/a-beginners-guide-to-fauna/
CHICAGO
" » A beginner’s guide to Fauna." samaby | Sciencx - Accessed . https://www.scien.cx/2021/09/13/a-beginners-guide-to-fauna/
IEEE
" » A beginner’s guide to Fauna." samaby | Sciencx [Online]. Available: https://www.scien.cx/2021/09/13/a-beginners-guide-to-fauna/. [Accessed: ]
rf:citation
» A beginner’s guide to Fauna | samaby | Sciencx | https://www.scien.cx/2021/09/13/a-beginners-guide-to-fauna/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.