DEV Community

Nikhil karkra
Nikhil karkra

Posted on

GraphQL - React Apollo with Demo

I have built a basic Employee management application using React Apollo. It takes a lot of time for me to understand the terminologies used in react apollo. so, I thought of sharing some common methods and terms of Graphql apollo with you.

Below is the demo of my app

You can checkout my code here

Final Output of the Demo

Alt Text

Component View of the App

Alt Text

Key React-apollo Terminologies used in the demo

HttpLink

HTTP Link takes an object with some options on it to customize the behavior of the link. If your server supports it, the HTTP link can also send over metadata about the request in the extensions field.

import { HttpLink } from "apollo-link-http";
const link = new HttpLink({
  uri: "http://localhost:1234/"
});

ApolloClient

The Apollo Client constructor takes a small number of options, of which two are required.
1. link - Apollo Client requires an Apollo Link to serve as the network layer.
2. cache - The second required argument for using Apollo Client is an instance of an Apollo Cache. The recommended cache is the apollo-cache-inmemory which exports an { InMemoryCache }

//client.js
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";

const link = new HttpLink({
  uri: "http://localhost:1234/"
});

const cache = new InMemoryCache();
const client = new ApolloClient({
  link,
  cache
});
export default client;

ApolloProvider

It is a component that leverages React's Context API to make a configured Apollo Client instance available throughout a React component tree.

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { ApolloProvider } from "@apollo/react-hooks";
import client from "./client";
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
<ApolloProvider client={client}>
      <App />
</ApolloProvider>
    , document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

gql

JavaScript template literal tag that parses GraphQL queries into an abstract syntax tree (AST)

//queries.js
import gql from "graphql-tag";
export const ALL_EMPLOYEES_LISTS = gql`
  query AllEmployeeLists {
    employees {
        name
        id
        role
        createdAt
        img
        employer
    }
  }
`;
export const CREATE_EMPLOYEE = gql`
  mutation createEmployee($newEmployee: NewEmployeeInput!) {
    addEmployee(input: $newEmployee) {
        name
        id
        role
        createdAt
        img
        employer
    }
  }
`;
export const UPDATE_EMPLOYEE = gql`
  mutation updateEmployeeData($updateEmployee: updatedEmployee!) {
    updateEmployee(input: $updateEmployee) {
        name
        id
        role
        createdAt
        img
        employer
    }
  }
`;
export const DELETE_EMPLOYEE = gql`
  mutation deleteEmployeeData($deleteEmployee: EmployeesId!) {
    deleteEmployee(input: $deleteEmployee) {
        id
    }
  }
`;

useQuery

The useQuery React hook is the primary API for executing queries in an Apollo application. To run a query within a React component, call useQuery and pass it a GraphQL query string. When your component renders, useQuery returns an object from Apollo Client that contains loading, error, and data properties you can use to render your UI.

import { useQuery } from "@apollo/react-hooks";
const { data, loading, error} = useQuery(ALL_EMPLOYEES_LISTS);

useMutation

The useMutation React hook is the primary API for executing mutations in an Apollo application. To run a mutation, you first call useMutation within a React component and pass it a GraphQL string that represents the mutation. When your component renders, useMutation returns a tuple that includes:

  • A mutate function that you can call at any time to execute the mutation
  • An object with fields that represent the current status of the mutation's execution like update, variables, etc.
import { useMutation } from "@apollo/react-hooks";
const [deleteEmployeeData, deleteReponse] = useMutation(DELETE_EMPLOYEE);

update in useMutation

update function used to update the cache after a mutation occurs. Syntax as shown below.

update(cache,mutationResult })

readQuery & writeQuery

  • The readQuery method enables you to run GraphQL queries directly on your cache.
  • If your cache contains all of the data necessary to fulfill a specified query, readQueryreturns a data object in the shape of your query, just like a GraphQL server does.
  • If your cache doesn't contain all of the data necessary to fulfill a specified query, readQuerythrows an error. It never attempts to fetch data from a remote server.
  • writeQuery - This method is used to write arbitrary data to the cache. If you reload your environment, these changes will disappear.

Below is the example of useMutation with update method

const [createEmployee] = useMutation(CREATE_EMPLOYEE, {
    /***Updating the local cache****/
    update(cache, { data: { addEmployee } }) {
      const data = cache.readQuery({ query: ALL_EMPLOYEES_LISTS }); 
      cache.writeQuery({
        query: ALL_EMPLOYEES_LISTS, // query to update
        data: { employees: [addEmployee, ...data.employees] }
      });
    }
  });

Basic optimistic UI using optimisticResponse

Let's say we have an "Add employee" mutation, and we want the UI to update immediately when the user submits the mutation, instead of waiting for the server response.
The main way to get GraphQL data into your UI components with Apollo is to use a query, so if we want our optimistic response to update the UI, we have to make sure to return an optimistic response that will update the correct query result
Here's what this looks like in the code:

/***Employee Create Methods ****/
  const onSubmit=(input)=>{
    console.log(input)
    createEmployee({
      variables: { newEmployee: input },
      optimisticResponse: {
        __typename: "Mutation",
        createEmployee: {
          __typename: "Employee", // return type of mutation
          id: Math.floor(Math.random() * 1000) + "",
          name: input.name,
          role:input.role,
          createdAt:Date.now(),
          employer: input.employer,
          img: "https://via.placeholder.com/300"
        }
      }
    });
  }

Feel free to comment if any doubt or any issue with the code.

Top comments (1)

Collapse
 
moatazabdalmageed profile image
Moataz Mohammady

Thanks @Nighil I was using apollo boost while my team leader asked me to use the latest version apollo client

your post helped me thanks