DEV Community

Cover image for Getting Started with React, Fauna and URQL
Akuagwu Philemon
Akuagwu Philemon

Posted on

Getting Started with React, Fauna and URQL

Written in connection with the Write with Fauna program.

Introduction

Using a Todo Application

Gif of the app we are migrating to Fauna

What we will be building

I feel the best way to learn is by doing. In this article to we will build a Todo app using URQL,
we will learn how to :

  • Setup URQL with React
  • Setting Fetch Options like “request headers”
  • Write queries
  • Write Mutation

What is URQL

URQL stands for Universal React Query Library. URQL is a GraphQL client that exposes a set of React components and hooks. It's built to be highly customizable and versatile so you can take it from getting started with your first GraphQL project all the way to building complex apps and experimenting with GraphQL clients. Please Note that we weill make use of Git , Redux , GraphQL, NodeJS and Reactstrap but we are going to concentrate fully on URQL.
You can get the finished project - URQL_TODO_APP

Prerequisite for the article

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

Getting started

Since we will be making use of the Fauna GraphQL API. Make sure you Sign up to Fauna and set up your GraphQL API. Fauna GraphQL api requires an authorization key which we will save as an Environment variable (for Security reason).

Step 1:
In the root level of your react application, create a file .env.local . In this file, add an entry for the generated key:

 REACT_APP_FAUNA_SECRET=fnAD7S71UlACBcBWehe5q06JQeDRNgJUiNTbvUoN
Enter fullscreen mode Exit fullscreen mode

NOTE:

  • The file should be named .env.local and not just .env
  • Environment Variables that would be used in a react application should start with “REACT_APP_”… else they won’t be imported by default
  • make sure 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. ##

Step 2:
Install relevant packages:
Using Yarn

   $ yarn add urql graphql
Enter fullscreen mode Exit fullscreen mode

Or Using npm

    $ npm install --save  urql graphql
Enter fullscreen mode Exit fullscreen mode

Update the index.js file in the root level of the application to the code below

   import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import { createClient, Provider } from 'urql';
    // Create a Urql graphql client
    const client = createClient({
      url: 'https://graphql.fauna.com/graphql', /// the graqhql api url
      fetchOptions: { // fetch options  you which to add
        headers: { // request header
          // authorization token imported from .env.local
          authorization: `Bearer ${process.env.REACT_APP_FAUNA_SECRET}`, 
        },
      },
    });
    ReactDOM.render(
      <React.StrictMode>
        <Provider value={client}>
          <App />
        </Provider>
      </React.StrictMode>,
      document.getElementById('root')
    );
Enter fullscreen mode Exit fullscreen mode

Code Explanation:

  • createClient - Create a GraphQL client to enable interaction with the GraphQL api
  • fetchOptions - This option allows us to customize the options that will be passed to fetch when a request is sent to the given API url
  • Provider - A Wrapper component that enables every other component inside it to make use of GraphQL queries that will be sent to our API
  • url - the GraphQL API url
  • headers - custom headers needed by the API , this might be needed for Authentication, Authorization, e.t.c.

If you have been following along so far, congratulations, you are ready to start writing queries and Mutations

CRUD (Create, Read, Update, Delete) Operations With URQL

After you setup URQL, the next step is to Create a todo task.

Create Task

    import { useMutation } from 'urql';
    /*At the top of your of your file */
    // ...code

    /* Inside a React component */
      const CreateTodo = /* GraphQL */ `
        mutation($data: TodoInput!) {
          createTodo(data: $data) {
            _id
            name
            completed
          }
        }
      `;
      const [result, createTodoItem] = useMutation(CreateTodo);


     function  onSumbit() {
      const newItem = {
          data: {
            name: name,
            completed: false,
          },
        };
        createTodoItem(newItem).then((result) => {
            const {
              data: { createTodo },
            } = result;
            props.addItem(createTodo); // passing data our redux store
          });
    }
Enter fullscreen mode Exit fullscreen mode

Code Explanation:
For a better understanding of the code I suggest you go through the The Project Repo, Navigate to src/components/itemModal.js

  • CreateTodo - is a GraphQL mutation. You can use the GraphQL playground and Schema to structure your mutations and queries.
  • useMutation - is imported from urql and is used to execute GraphQL mutations. it return a tuple.
  • result - The first item in the tuple contains fetching, error, and data — it's identical since this is a common pattern of how urql presents operation results.
  • createTodoItem - The second Item in the tuple is a function where you pass graphQL variables. Notice in the GraphQL mutation we passed $data as a variable, and in the createTodoItem function we passed data as an argument in the function call.

Get All tasks (GET)

    import { useQuery } from 'urql';
    /*At the top of your of your file */
    // ...code

    /* Inside a React component */
     const [result] = useQuery({
        query: `
        {
          allTodos {
            data {
              _id
              name
              completed
            }
          }
        }
      `,
      });
      const { data, fetching , error} = result;
Enter fullscreen mode Exit fullscreen mode

Code Explanation:
For a better understanding of the code I suggest you go through the The Project Repo, Navigate to src/components/TodoList.js

  • useQuery - Is used to make GraphQL query request. Similar to the useMutation hook, the useQuery hook returns a tuple but with only one Item, which is the result (response) of the query.
  • result - is the response data from a query request, it is an object with three properties,
    • data
    • fetching
    • error
  • data - basically response data from the server
  • fetching - This is the state of the request, It is initially false, when a request is completed it updates to true.
  • error - This propertty contains the error message if any error occurs, it is initially undefined but updates to an error message from the server if an error occurs

Mark as Completed (Update)

    import { useMutation} from 'urql';
    /*At the top of your of your file */
    // ...code

    /* Inside a React component */
    const updateTodo = /* GraphQL */ `
      mutation UpdateTodo($id: ID!, $data: TodoInput!) {
        updateTodo(id: $id, data: $data) {
          _id
          name
          completed
        }
      }
    `;
    const [updateResult, updateTodoItem] = useMutation(updateTodo);
     const newItem = {
            id: props.id,
            data: {
              name,
              completed: props.completed,
            },
          };
      updateTodoItem(newItem).then((result) => {
      // result here is similar to  updateResult (first item returned by useMutation)
      const {
          data: { updateTodo },
        } = result;

      });
Enter fullscreen mode Exit fullscreen mode

Code Explanation:
For a better understanding of the code I suggest you go through the The Project Repo, Navigate to src/components/updateItemModal.js.

  • UpdateTodo - is a GraphQL mutation. You can use the GraphQL playground and Schema to structure your mutations and queries.
  • useMutation - is imported from urql and is used to execute GraphQL mutations. it return a tuple.
  • result and updateResult - The first item in the tuple contains fetching, error, and data — it's identical since this is a common pattern of how urql presents operation results.
  • updateTodoItem - The second Item in the tuple is a function where you pass graphQL variables. Notice in the GraphQL mutation we passed $id and $data as variables, and in the updateTodoItem function we passed them as arguments in the function call.

Delete tasks (DELETE)

    import { useMutation} from 'urql';
    /*At the top of your of your file */
    // ...code


    /* Inside a React component */
    const deleteTodo = /* GraphQL */ `
      mutation DeleteTodo($id: ID!) {
        deleteTodo(id: $id) {
          _id
          name
        }
      }
    `;
      const [, deleteTask] = useMutation(deleteTodo);
       deleteTask(data).then((result) => {
            const {
              data: {
                deleteTodo: { _id: deletedDataId },
              },
            } = result;
          });
Enter fullscreen mode Exit fullscreen mode

For a better understanding of the code I suggest you go through the The Project Repo, Navigate to src/components/DeleteButton.js.

  • deleteTodo - is a GraphQL mutation. You can use the GraphQL playground and Schema to structure your mutations and queries.
  • useMutation - is imported from urql and is used to execute GraphQL mutations. it return a tuple.
  • result - The first item in the tuple contains fetching, error, and data — it's identical since this is a common pattern of how urql presents operation results.
  • deleteTask - The second Item in the tuple is a function where you pass GraphQL variables. Notice in the GraphQL mutation we passed $id as a variable, and in the deleteTask function we passed them as arguments in the function call.

Conclusion

In this Article we learnt How to Setup URQL with React, create data, fetch data, update data and delete data. URQL is a really wonderful library to look into, You can checkout URQL documentation for more Information.

Top comments (1)

Collapse
 
guibibeau profile image
Gui Bibeau

Is it ok to expose your API key in the client like this?