umma.dev

GraphQL

GraphQL is a fast and efficient query language for APIs. When compared to REST, it is known for it’s performance when retrieving data and easiness for implementation. It can be incorporated into many tech stacks.

Structure

Let’s say you’ve got a back-end of some sort, it could be an end-point, a database you’re retrieving data from. On the front-end, to get this data via a server or rather you send a GraphQL query via this server.

The server can come in a variety of different flavours from GraphQL.js to Apollo Server to Express GraphQL to name a few.

Here is an example of a GraphQL query end-to-end:

type Person {
  name: String,
  age: number
}
{
  person(name: "GraphQL") {
    age
  }
}
{
  "person": {
    "age": 20
  }
}

Set Up

This set up includes create-react-app and apollo.

npx create-react-app [app-name]

npm install @apollo/client graphql

Head over to index.js and import the following:

import { ApolloClient, InMemoryCache, ApolloProvider, gql } from '@apollo/client';

You will also need to add the following to your index.js:

const client = new ApolloClient({
  uri: 'www.you-api.com',
  cache: new InMemoryCache(),
});

What’s a URI and Why a Cache?

The URI specifies the URL of the GraphQL server

Cache is an instance of InMemoryCache, which Apollo Client uses to cache the query results after they are fetched.

So now the client is ready to fetch data. To test it, you need to send a query to the GraphQL server.

Here is an example of this within index.js:

client
  .query({
    query: gql`
      query GetLocations {
        locations {
          mame
          age
        }
      }
    `,
  })
  .then((result) => console.log(result));

Here is the full code for index.js:

import React from 'react';
import * as ReactDOM from 'react-dom/client';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import App from './App';

const client = new ApolloClient({
  uri: 'www.your-api.com',
  cache: new InMemoryCache(),
});

const root = ReactDOM.createRoot(document.getElementById('root'));

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

Here is the code for App.js to query the data via the useQuery hook, alongside a function called DisplayLocations.

import { useQuery, gql } from '@apollo/client';

export default function App() {
  const GET_LOCATIONS = gql`
  query GetLocations {
    locations {
      id
      name
      description
      photo
    }
  }

  return (
    <div>
      <h2>My first Apollo app 🚀</h2>
    </div>
  );
}

Let’s say you create a function to display locations:

function DisplayLocations() {
  const { loading, error, data } = useQuery(GET_LOCATIONS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error : {error.message}</p>;

  return data.locations.map(({ id, name, description, photo }) => (
    <div key={id}>
      <h3>{name}</h3>
      <img width="400" height="250" alt="location-reference" src={`${photo}`} />
      <br />
      <b>About this location:</b>
      <p>{description}</p>
      <br />
    </div>
  ));
}

So to display this data in App.js, you will render it as follows:

  return (
    <div>
      <h2>My first Apollo app 🚀</h2>
      <br/>
      <DisplayLocations />
    </div>
  );
}

For more information, check out the Apollo docs here.

Example

GraphQL vs REST

When a REST api is called on the front-end, you will get ALL the data back for the end-point you are calling. In a React application this can be taxing, especially when it comes to re-renders and data fetching.

With GraphQL, you can query parts of the end-points and get back ONLY the data needed, leading to an increase of speed within your application.