GraphQL + Apollo - Flash Debrief

June 22, 2020 | 8 minute read

What is GraphQL? It is a query language that wraps around an existing database to make requests to APIs differently. I implemented GraphQL on the latest iteration of the Yijing-Ball-Z app.

GraphQL + Apollo - Flash Debrief

What is GraphQL? It is a query language that wraps around an existing database to make requests to APIs differently. I implemented GraphQL on the latest iteration of the Yijing-Ball-Z app.

Look at the traditional backend diagram:

Screen Shot 2020-06-11 at 5 46 58 PM

We make requests to specific endpoints to get some data. Above you can see the REST paradigm, with either POST, GET, PUT etc requests. With deeply nested endpoints e.g. users/userId/posts we could make at least multiple requests just to get user posts.

Now GraphQL tries to solve this differently from REST APIs. So first we need to make our server into a GraphQL backend server.

Screen Shot 2020-06-12 at 10 32 21 AM

So you can see first that there’s only one endpoint exposed instead of multiple endpoints. Then from here we make all requests to either a query (ask/read data) or mutation (create/update/delete data). These requests look pretty much like JSON objects. So we don’t need multiple endpoints to just access data.

Playing with GraphQL

Take a look at the GraphQL Playground. Here we can start playing with GraphQL queries for a sample project. Please refer to GraphQL documentation for queries help. You can implement this playground when you build your own GraphQL server.

Here’s an example of a query you can do on this playground:

Screen Shot 2020-06-12 at 10 48 35 AM

Inside our query we can only make certain requests as defined on the db as things we can take. If you look at the schema you can see what is available. We can define our schema in many ways for example a Person schema:

type Person {
  id: ID!
  name: String!
  age: Int!
}

The exclamation mark means mandatory. Items is an array, then inside items there’s an item. Then if you click on docs you can see the type of queries you can make.

Screen Shot 2020-06-12 at 10 52 55 AM

If we pass then ID of collection we can get a collection, we can also get a collection by a title. So whatever we see we have access it means it was built by the backend server and made available to us. Here’s an example of a query we can make:


query {
  collections {
    id
    title
  }
}

If you click run with this query then you get an object containing all the collections. You can also pass in items to get the items as specified on the schema. As this:

query {
  collections {
    id
    title
    items {
      id
      name
      price
    }
  }
}

Now what if you wanted to query by ID:

query {
  collection(id: "cjwuuj5bz000i0719rrtw5gqk") {
    title
  }
}

For mutations we’ll start with the mutation keyword. Back to our Person example consider this:

mutation {
  createPerson(name: "Bob", age: 36) {
    name
    age
  }
}

Now in your schema you might define it as such:

type Mutation {
  createPerson(name: String!, age: Int!): Person!
}

Pretty easy right?

Note: as React developers, we will usually only concern ourselves with the frontend implementation of GraphQL. If you’re curious as to how to build a GraphQL server, below are some resources, as well as a list of some popular options out there for building such a server:

Introduction to Apollo

Ensure you install it as well as GraphQL:

yarn add apollo-boost react-apollo graphql

Apollo client lets us use the GraphQL API toolkit. Apollo also caches the data so we don’t double request it.

Take a look at the index.js on the following GraphQL example repository. We could test making a query using gql function as this:

client.query({
  query: gql`
  {
    getCollectionsByTitle(title: "hats") 
    {
    id
    title
    items {
      id
      name
    }
   }
  }
  `
}).then(res => console.log(res))

Note how here the client.query returns a promise.

Apollo Container

On the example repo take a look at the Collections-Ov-GraphQL component. This container does the fetching and includes loading attribute we can use. You might see how Apollo extrapolates a lot of the verbose promise code, resolving etc. So it feels like synchronous even though we’re fetching the database.

GraphQL vs Redux

There are benefits in both. Redux has very fleshed out architecture. You can actually use both in the same app, however you might actually be having to handle two pieces of state management. So usually Apollo replaces Redux but this is up to you, but if you keep both then it could affect the single source of truth concept.

Here’s how Redux works:

Screen Shot 2020-06-12 at 1 19 23 PM

Here’s how Apollo works:

Screen Shot 2020-06-12 at 1 23 38 PM

Local cache replaces our reducer. We access/modify our data through a query or mutation. These resolver functions can get or modify data and they can get it from local cache as internal state.

Mutations on the Client (Frontend)

Mutations are a bit different and you can check the example Repo and specifically the graphql folder. Basically you create a resolvers.js file that handles the mutations inside a graphql folder in src.

extend keyword in GraphQL behaves a little bit different than JS, read more here. Another key concept are resolvers methods, the GraphQL documentation can explain them in detail. Here the cache object you can read more about it.

Notice also how we import and pass to our client in index.js the resolvers and typeDefs defined on resolver.js. Here for example the toggleCartHidden mutation is used on header-container that is in charge of dealing with the graphql querying using the Query element and then renders the header-component.

You might also notice in resolvers.js the @client this tells Apollo to look on the local cache not the server. Finally on the cart-icon container you might see that it uses compose and graphql functions, that look kind of like Redux, you can access the documentation to see how to implement in detail.

Mutations can be a complex topic, so read on the resources and make your own tests. Complete Apollo documentation in the link here. However do have in mind that if you would like to implement it consider having a container that deals with the graphql logic then the actual presentational component so the latter can be reused as it is not solely related to graphql.

What’s Next

  • Build your own GraphQL server from scratch here.
  • Checkout my GraphQL implementation using Vanilla JS + Rails API (frontend/backend).

Conclusion: Should You Use GraphQL?

GraphQL can be very challenging since there’s so much to learn at the beginning. I tried to touch on some interesting concepts, with demo projects both in React and Vanilla JS. The rest is for you to keep digging and motivate yourself to start implementing it in your own project.

Do note that the issues with REST that GraphQL tries to solve, are important propositions. The problem with implementations such as Apollo is that it needs both backend and frontend adoption. Setting up backend with can be hard so taking this risk might be difficult. Also this tech is new, not like Redux which there are so many resources out there. Apollo client and GraphQL are relatively new and the paradigm might change. So for now learning GraphQL is great, but do keep your strong skills on Redux, since on scaling it performs really well, and has been industry tested.