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:
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.
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:
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.
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:
- Backend Implementation Example. Uses Prisma
- Hasura
- Apollo Server
- Quick way to build a GraphQL server: graphql-yoga
- A quick step by step guide on how to set up your own GraphQL server
- Here’s my backend Rails API + GraphQL Implementation.
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:
Here’s how Apollo works:
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.