Migrating a React project from AWS Appsync to Fauna
Tags: fauna, serverless, react, graphql
Published: 2020-12-05 23:27:09

# **Introduction**

In 2020, there is a variety of technology stack that can be utilized to create a website, and sometimes a developer may require to migrate an already existing project from one tech stack to another. In this article we are going to migrate an AWS Serverless (Appsync)

Graphql application to a Fauna Graphql Application.

## **The application we are Migrating**

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/205d9acf-851c-4f61-8156-2ee6e7943224)

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/3eefc868-39e2-4cdd-bb92-34252a02728b)

The application is a “todo application” that uses AWS DynamoDB as its Database and AWS Appsync service currently. We are going to convert the current application to a Fauna application.

## **Why Fauna**

[Fauna](https://fauna.com/) is a serverless database that provides you with CRUD capabilities and abstract a lot of “Under the hood” processes You might want to use Fauna because:

- Fauna is fast and scales well
- Fauna is relatively easy for beginners to get started with
- The current project rely on two AWS services (Appsync and DynamoDB) but with Fauna it will rely on one
- Fauna currently uses the [](https://fauna.com/blog/distributed-consistency-at-scale-spanner-vs-calvin) [Calvin](https://fauna.com/blog/distributed-consistency-at-scale-spanner-vs-calvin) protocol to maintain several full and consistent copies of the data, these data are called _replicas,_ with the ability to both read and write on every node.
- The learning curve for Fauna is relatively less than learning AWS appsync

## **Prerequisite for the Article**

- Basic Knowledge of React
- Basic Graphql knowledge
- Using Apollo with React
- NodeJS Installed on your PC
- Knowledge of Redux will be a plus (as we will be using redux for state management)
- Git & GitHub knowledge

## **Getting Started**

To Get Started and follow along do the following :

Clone the repo from GitHub by running the following command in your git bash terminal

```bash
 $ git clone https://github.com/PhilzAce1/FaunaDB-Todo-app.git
```

Git checkout to branch “ready-amplify”

```bash
$ git checkout ready-amplify
``` 

Install all dependencies required to make the application work

```bash
$ yarn install
```

Lastly for your application to work You will have to setup the Appsync service using Amplify or on the Amazon console

## **Overview of the Current application**

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/1c01a21d-de6d-4102-8648-c546d810c8b0)

The Current Application makes use of the “Aws-amplify” package as the GraphQL client, we are going to be making mutations and queries using the Aws Appsync package

**Graphql Client setup**

**Schema**

```graphql
# Todo -> GraphQL type

type Todo {

name: String! #title of the task

completed: Boolean #task completed

}

# Graphql query type -> Specify Queries you want to make available

type Query {

allTodos: [Todo!] #return all Tasks created

# fetch tasks by the value of their "completed property

todosByCompletedFlag(completed: Boolean!): \[Todo!\]

}
```

## **Setting up Fauna**

Setting up Fauna is very easy and I am going to walk you through from scratch :

**Step 1: Go to the Fauna website [Fauna](https://fauna.com/)**

if you have an account, you can log in, if you do not have an account, simply create one

Creating an account is really easy and straightforward.

**Step 2:**

Create a new Database

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/5c0103d0-ecc6-448a-ae48-2c6beb8fdb62)

**Step 3:**

Give the Database a name.![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/dd4fc6e1-f621-418e-be28-beab27fa6cb9)

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/3d13d852-167a-46e2-a54d-300961e5bb9a)

**Step 4:**

In this Step, I will compare an AWS Appsync Graphql Schema with a Fauna Schema

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/a6946dff-0c29-4f4b-a5de-53ce391ac4b5)

On the right-hand side we have the AWS Appsync schema, the “@model” directive will create a CRUD resolver for the “Todo” Graphql Type,

Similarly on the Left Fauna will automatically Create Resolvers based on the schema, you need not provide “directives”

**Step 5:**

Import the GraphQL schema that you created

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/af10be29-8453-4132-bfe8-a4d2fbdc9106)

After importing the Graphql schema, you will be routed to a Graphql playground where you can test and create queries and mutations. Click on the “Docs” tab in the sidebar to check out the available queries and mutations.

## **Provisioning a New Database Key**

After you create and configure your database you need a way for client applications to access it.

The key generated will be used to specify and authenticate our Fauna database. It will also help us access the database to perform, create, read, update, and delete activities from the Client (React) application. Note that authentication and authorization are topics on their own .

The application key generated has a set of permissions that are grouped together in a “role”.

We begin by defining the role that has the necessary CRUD operations on tasks

**Step 1:**

Click on the “Security” tab and then the “New key” button

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/e29e4bcd-a635-4658-b77d-5698ea5b91ce)

By default, there are two roles, “admin” and “server”. We could use these roles for our key, but it is not a good idea because they provide authorization for “Database level operations” such as creating a new collection or even deleting the database itself.
In that case, create a “Custom role”.

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/80acaa64-db5e-4bb1-a89b-77afc74a1c70)

Then you click on the “New Custom role” button

**Step 2:**

Select permissions and then save

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/ebcac864-4f7c-4b2d-9a87-8ea7aef3af68)

**Step 3:**

After you save the new Role. You will be able to access it when you want to create a new Key

Simply create a new Key.

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/abae9f5f-ee2e-4e72-af2e-c1da16422d80)

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/15a73b02-30b0-431d-93f4-e5a96d09793c)

This is the access key that will be used to authenticate your connection with the Fauna database you created.

For security reasons, we are going to load the Key from a “.env.local" file which is in the root level of your react application.

In this file, add an entry for the generated key:

`REACT_APP_FAUNA_SECRET=**fnAD7S71UlACBcBWehe5q06JQeDRNgJUiNTbvUoN**`

NOTE:

- The name of the file should be `.env.local` and not just `.env`
- Environment Variables that should be used by a react application should start with “REACT_APP\_”…
- make sure that you also have a `.gitignore` file in your project’s root directory that contains `.env.local` so that your secrets won’t be added to your git repo and shared with others.
- You’ll have to explicitly stop and restart your application with `yarn start` in order to see these changes take place.

## **Connecting React to Fauna**

With AWS Appsync we simply made use of the “aws-amplify” package to interact with the graphql api. But with Fauna we are going to be making use of [](https://www.apollographql.com/) [Apollo client](https://www.apollographql.com/)<span style="text-decoration: underline;">.</span>

To install the relevant Apollo packages we’ll need, run:

```bash
yarn add @apollo/client graphql @apollo/react-hooks
```

Now in your `src` directory of your application, add a new file named `client.js` with the following content:

```javascript
import { ApolloClient, InMemoryCache } from "@apollo/client";

export const client = new ApolloClient({

uri: "https://graphql.fauna.com/graphql",

headers: {

authorization: `Bearer ${process.env.REACT_APP_FAUNA_SECRET}`,

},

cache: new InMemoryCache(),

});
```

What the code is doing here is simply configuring Apollo to make requests to our Fauna database. Specifically, the uri makes the request to Fauna itself, then the authorization header indicates that we’re connecting to the specific database instance for the provided key that we generated earlier.

Note: The authorization header contains the key with the “CustomRole” role (the role we created earlier), and is currently hardcoded to use the same header _regardless of which user is looking at our application._ The tasks created by a user will not be specific to that user.

After that, We will replace the code in the `index.js` with

```javascript
import React from 'react';

import ReactDOM from 'react-dom';

import { ApolloProvider } from '@apollo/client';

import './index.css';

import App from './App';

import { client } from './client';

ReactDOM.render(

<React.StrictMode>

<ApolloProvider  client={client}>
<App />

<ApolloProvider \>

<React.StrictMode \>,

document.getElementById('root')

);

```

Let’s compare the AWS Appsync configuration with the Apollo configuration in the `index.js`

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/a8e353df-c201-4285-a8cb-73a1bc00dd9f)

On the left, you can see the configuration for the AWS Appsync and on the right, we have the configuration for Apollo.

You can test your app by running `Yarn start` if everything still works

<!--  ![partying face](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/e1d7bdef-2ac4-4290-8fee-b2c0221301e1 'partying face')![partying face](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/bc0eff2b-18c1-4b4f-9bd3-6a88e188da76 'partying face') ![partying face](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/f6d731c1-b507-4f9e-aace-8fe5f02b6354 'partying face')  -->

Congratulations You are a rock star

## **Migrating CRUD operations**

The next thing you have to do is to Migrate the CRUD operations. Since it is a Todo application, we are going to be creating tasks, marking them as completed, getting already created tasks and finally deleting them Using Fauna and React-Apollo client. We will Compare Appsync and Fauna Mutations and queries

**Adding tasks to the Todo App**

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/e97f6849-e25a-40ae-861e-9488d502fcbd)

Explanation:

On the Left hand (Appsync) , Notice the structure of the mutation. The `API` and `graphqlOperation` functions are imported from `aws-amplify` package.

On the Right-hand (Apollo),

- `useMutation` - is imported from @apollo/react-hooks and is used to execute graphql mutations
- `gql` - is imported from “graphql-tag” package that we installed initially and it’s needed when making graphql api calls with Apollo
- `createItem` - useMutation hook returns an array of functions and objects, the first element of the array is a function used to make mutations. The arguments passed to the mutation is the variable of the graphql mutation
- `loading` - the second element of the array returned from the “useMutation” hook is an object. loading becomes “true” after the mutation has been executed successfully
- `createTodo` - is a const that contains the graphql mutation. You can test and structure a mutation using the graphql playground

**Getting all Tasks**

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/7365aa28-40e1-4099-bb7d-19547a894215)

Explanation :

The `useQuery` hook is similar to the `useMutation` hook. `useQuery` gook is used to make graphql query request. It returns an Object. “data” property contains the response data of the query, while the “loading” property is the status of the request’s completion

**Deleting Tasks**

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/115e7f1c-c4d3-41e9-a63c-fab220b70dc9)

Explanation:

The `onComplete` callback function is called when a mutation is resolved. `deleteTask` is a function used to perform a delete mutation. The arguments passed are the variables in the graphql mutation.

**Marking task as Complete (Update)**

![](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/7bc77f69-87a8-4afc-af00-7583350b117d)

Note:

`updateTask` function is similar to the previous mutations, but the first property of the variable object is the “id” property. The data property will contain all Fields in the database that you wish to update.

## **Conclusion**

<!-- ![partying face](https://usecloudpressstorage.blob.core.windows.net/hosted-document-images/cd73905e-5ffb-49b5-8e69-8eddc6c8571d 'partying face') -->

If you made it this far congratulation In this article we migrated an AWS Appsync application to a Fauna application by creating a new database, connecting the fauna database to our react application and then we compared the structure of queries and mutations in Appsync and Fauna. Fauna is a really cool innovation and it is something I will advise every developer to start using. You should also check out their [official documentation](https://docs.fauna.com/fauna/current/) for more information.