Chapter 1
Fauna is a great serverless database created to work as a data API, its functionality makes it great to work with serverless frameworks like next.js. In this series, we will use Fauna’s power to create a social network back-end structure. This time we won’t be using GraphQL, instead, we will use all the functionality provided by Fauna’s dashboard and shell.
Why Fauna?
Fauna’s storage model is a non-structured database, the flexibility of such a database allows the design, functionality, and business model to be flexible as well. Most changes in relationships will not represent changes in the rest of your structure, it feels like you were already thinking of that feature when you started.
Even with the non-structured database, it is easy to set up indexes that work like lookups without having to bring a large set of data, saving you lots of bandwidth and improving your site’s performance.
Serverless means you can expand for as many operations as you need, Fauna takes care of everything and prices are very competitive. Don’t just take my word on it and check on Fauna's official website, simulate your monthly costs based on your site’s needs and register here.
Fauna has the option to create your own User Defined Functions, these functions can be useful to improve your site’s performance even further, it handles some tasks locally, reduces API calls from your servers, helps you manage actions more consistently, it can even help you protect your database (which you’ll learn more about in next chapters)
Social network overlook
We want to exploit the most potential out of Fauna, in this series, we will do it by creating a social network. For this, we will have user authentication, password recovery, follow users, chats, publishing, liking, and commenting posts. We will retrieve this data via APIs while we integrate it with Next.js, a serverless react framework.
Let’s start by outlining our database. We want to know how our data will be related between different collections as well as how indexes will retrieve information from a collection based on the information from another collection, the diagram below will give us an approach that is easy to understand and will help us keep track of the app’s functionality and what we will need to build in order to make it work. Note the internal reference in the user’s collection, this is the user’s ID and will be constantly used throughout the app.
I know these connections might seem overwhelming at first, but when we start to create our database, they will become an obvious need for a social network and we will go over every one of them as we advance in the series.
As you can see, the Users are the center of a social network. Therefore, everything is connected to them at this point. The Users collection will have the user’s email, the username, a profile description or bio and a profile picture; Fauna stores passwords in a separate collection that can’t be accessed, even by admins, making it easier and safer when someone reads the documents in the User collection. Also, Fauna stores a reference for the user which we will use for all our relationships.
Tokens is an internal Fauna collection, Fauna doesn’t show too much from this collection, however, we can use it to save some information about the User’s login, such as the navigator used or the amount of active logins such user has. You can use this to limit the number of logins a user can have, or to restrict their use to certain regions.
Also, the UpperRoles collection is used to give specific hand-picked Users additional permits using ABAC. This way, we will use regular users and promote them to moderators, admins, etc.
All the other collections will be defined as we need them.
Note: If you want to follow through our examples, you need to install FaunaDB to use it on your preferred Command shell, and install node.js to setup a local server and get your APIs running.
Setting up with Next.js
This time, we will set up our project on Next.js. Fauna does not require a full-time connection between the Client and the Server, it works like an API: You open a connection, make a request, get a response, close the connection. Same with Next.js, your server can get requests all the time, but your connections will only last as long as the request.
If you want to learn how to use Next.js, follow this link (Next.js is a framework based on React, thus, you may need to know some React before diving into Next.js)
For this series, we will start by using the example from Fauna found in this page, we will cover the things you need to get your APIs running. Thus, you can read the tutorial or continue reading this chapter.
Use your explorer or command Shell (E.g. Windows Powershell, Gitbash) to navigate to the folder you want to download our example to.
You can use any of these commands to download the example from Next.js repository:
npx create-next-app --example with-cookie-auth-fauna with-cookie-auth-fauna-app
or
yarn create next-app --example with-cookie-auth-fauna with-cookie-auth-fauna-app
Navigate inside the newly created folder and launch the command npm install
or yarn
to download the required libraries.
If you are working on Windows 10, you should have a folder which looks like this:
To access the database, Fauna uses keys that are created from Fauna’s dashboard and are deleted from there as well, a master key is needed to create users and contact the database to log in an existing user. When a user logs in, they get a key that needs to be saved on a secure cookie, the file .env.local.example needs to contain the master key from Fauna. So, let us set up our database to use it with this fresh Next.js project
Setting up your database and your server keys
If you’ve already got into Fauna, read some documentation and completed the tutorial on the Database, you may already know how to create your database and your server key and can skip this part.
If you haven't signup for Fauna yet, you can do it on this link
On the dashboard, you can create a new database from the main view
Click on the button marked with “NEW DATABASE” and input the name of your new database. This time we won’t need demo data as we will be using our own in this series.
Great, now you have a new database, but you can’t access it yet from outside the Fauna’s dashboard. Let’s change that.
On the menu on your left, click Security and Create new key, assign it the server role and click save (you can add an optional name if you want, but it won’t be used anywhere, it’s merely cosmetic).
Note: This key will only be shown once, so you will need to add it to your .env.local.example file at once. If you lose it for some reason, you can always create a new one. Just make sure to revoke the older one.
When you add the secret to the .env.local.example file, change its name to .env, so Next.js can read it.
When you put your key on your environment variable, it should look like this:
That one is my key, yours should be different.
Create a collection called Users and an index called users_by_email, the index’s source should be the Users collection and the terms should be data.email, also, check the box Unique to prevent duplicate entries, this means the index will return the reference of the user that matches the email you request.
The index creation menu should look like this:
Let’s create a test user and see if it works, for this, we will use the Fauna’s dashboard shell, we will create a method for signup on our app later in this course.
The Create method creates a document in the collection you define in the first parameter with the data you define on the second parameter as an object. The object you provide can have the following fields:
- data: This field contains an object with all the data you want to save on your document, you can have as many fields inside this object as you need. Also, the index we created earlier will look at the field email and will try to match the email you provide for a search, more on that later.
- credentials (optional): This field contains an object with a password field which is a string with the user’s password, note that in a social network we only want users to log in, but in another scenario, perhaps a factory, we can separate collections for supervisors, engineers, operators, etc. Meaning any document in any collection can login if it has credentials set.
- delegates(optional): This field contains an array of references that will have the same permissions as this document. We won’t use this field on the series.
- ttl(optional): Time-To-Live, this is useful for stories, as they last only 24 hours, this field is a timestamp with the expiration date of the document.
Create(
Collection('Users'),
{
credentials:{password:'123456'},
data:{email:'testmail1@mail.com'}
}
)
When you execute the command above, you should see something like this on the Fauna shell:
Also, you can confirm on the Collections section that your user has been created on the Users collection.
As we mentioned earlier, Fauna stores password on a different collection that is not accessible (even by admins) meaning the user’s password will be safer and the user’s document can be read by other users with no need to keep hiding the password field.
Let’s try to log in with our new user from our local project in Next.js. open a command shell on your project folder and use the command yarn dev or npm run dev, depending on the package manager you have installed. When the command shell prints “event – compiled successfully”, open your browser and navigate to “localhost:3000”
Click Login and try to login with your fresh user. If you followed this example, you should see something like this:
You will see a different number, but if you compare with the document’s ref on the Users collection, it will match.
When you want to shut down the local server you’ve set up, you can hit ctrl+c twice.
At this point, we have set up a simple site using Fauna and Next.js examples. In the next chapter we will create methods to update the user’s profile, change the password, recover a lost password via email, learn how to use ABAC to limit the collections a user can access, make use of Fauna’s User Defined Functions to improve your performance and reduce latency, and create indexes that will help you get your posts in reverse order (newer first).
Top comments (0)