Topics

Featured in Development

As part of our core values of sharing knowledge, the InfoQ editors were keen to capture and share our book and article recommendations for 2018, so that others can benefit from this too. In this second part we are sharing the final batch of recommendations

Featured in Architecture & Design

Tanya Reilly discusses her research into how the fire code evolved in New York and draws on some of the parallels she sees in software. Along the way, she discusses what it means to be an SRE, what effective aspects of the role might look like, and her opinions on what we as an industry should be doing to prevent disasters.

Featured in Culture & Methods

Mik Kersten has published a book, Project to Product, in which he describes a framework for delivering products in the age of software. Drawing on research and experience with many organisations across a wide range of industries, he presents the Flow Framework™ as a way for organisations to adapt their product delivery to the speed of the market.

Featured in DevOps

The fact that machine learning development focuses on hyperparameter tuning and data pipelines does not mean that we need to reinvent the wheel or look for a completely new way. According to Thiago de Faria, DevOps lays a strong foundation: culture change to support experimentation, continuous evaluation, sharing, abstraction layers, observability, and working in products and services.

Turbocharge React with GraphQL

Key Takeaways

GraphQL can help you write expressive queries to pull as much or as little from your APIs as needed.

The GraphQL type system is tremendously powerful and can be used to validate and assemble flexible queries to your API.

Sometimes you still need REST. It’s OK, they can peacefully live side by side if needed.

GraphQL can be implement in any backend software, how will you integrate GraphQL in your backend services?

At an office in Boston, among the ping pong tables, beer on tap, and Ms PacMan, my client, Greg, sat across the table from me. Greg was a longer term and respected developer at this business. He asked me point blank “Is GraphQL production ready?”.

It was a fair question, since he never worked with GraphQL. Let’s be honest, GraphQL was only open sourced in 2015 and really just created as a standard in 2016. Is anyone besides Facebook really using GraphQL? Greg and his team were intimately familiar with REST and had built several apps in the last few years with REST. They leveraged Swagger for validation and documentation and it worked well for them. Hence the skepticism if GraphQL could really best REST as the communication conduit for apps.

Related Sponsor

Under the hood GraphQL is many things. First, it’s a buzzword. The cool kids are using it, so one might think it’s just a flash in the pan, techno babel, shiny, new hotness, or whatever the cool adjectives kids are using today. It’s much more, I assure you.

First, What GraphQL is NOT

Before we proceed, let’s dispel some frequent misconceptions surrounding GraphQL.

Misconception: A client can request any type of data in any way they want. For example, let’s say a client wants a list of all users and their favorite ice cream flavor. This can be made available to the client ONLY IF the schema on the server has defined this relationship.

Truth: The client is restricted to the data relationships defined on the GraphQL server.

Misconception: Is GraphQL compatible with MSSQL? No. It’s also not compatible with MongoDB, Oracle, MySQL, PostgreSQL, Redis, CouchDB, or Elasticsearch.

Truth: GraphQL doesn’t talk to databases. It receives the request from the client and it’s up to your backend software to use the requested data to query your data storage and return the data in a format compatible with your GraphQL schema.

Misconception: You have to choose between GraphQL or REST. Nonsense.

Truth: Offering both on your server can be done with contemptuous ease.

GraphQL is a Strongly-Typed Language

Seriously, GraphQL is a language? You betcha! Take a look at this simple definition below. You’re looking at definition for an image thumbnail.

GraphQL is All About Relationships

The power of GraphQL is found not only in the Types you define, but also how those types are related. If we look at an example Person type, we can add a relationship to another type, Address. This relationship is established by our definitions and now our clients can request a person and optionally receive a list of their addresses.

GraphQL is a Query Language

This part of GraphQL fits what most developers understand it to be, a query language. A replacement for REST. What makes it so much better than REST? Glad you asked.

Think of REST as two dimensional. GraphQL as three dimensional.

REST relies heavily on the URL as the resource you are interacting with, while GraphQL allows you to interact with many levels of resources. For example, a GraphQL client could request a Person by their ID, nested in the response could be a list of the person’s Friends (an array of Person). Within each of their friends, we can request to receive their addresses (an array of Address). Here is an example query demonstrating a query with this nested power.

REST is tightly coupled to HTTP status codes, such as 200 and 404. GraphQL does not use HTTP status codes, but instead uses an errors array in the response.

GET in REST can become unwieldy when having to specify IDs for multiple levels of resources, such as a post > comment > author > email. For GraphQL, this is handled nicely by leveraging the type definitions and relationships.

GraphQL automatically performs validation on your incoming data. For example, if we have an input defined such as you see below. If the client submits age as a string, GraphQL is going to throw an error, or if fname is missing, it will throw an error.

input Person {
# First name
fname: String!
# Last name
lname: String
# Age in years
age: Int
}

This is also true when the API is returning data. It will validate and format to match the defined schema. This is handy for example if you happen to query your database for a person record, and it accidentally sends the password field to the client. Gasp!!!!

It’s going to be OK, since GraphQL didn’t have a definition for the password, it will silently prune the password from the response. Hoorah!

GraphQL is Extendable

Let’s say you sit down to write your GraphQL schema and decide you would like to change the way dates are handled. Maybe you’d prefer them to be returned to the client as epoch timestamps instead of ISO strings. This is easily done by defining your own Scalar type for GraphQL to utilize and then you just need to define how this scalar parses and serializes data. Here is a custom Date scalar returning the date as an integer. You’ll notice there is a parseValue function to handle the data from the client and a serialize function to change the data before sending to the client.

Sure, GraphQL was only open sourced by Facebook in 2015, and only became a standard in 2016. It’s young, but it has a few things in its favor.

Long incubation history: Facebook, may have only open sourced it in 2015, but it had been developed back in 2012 and used by them well before they released it to the general public. It’s a little comforting knowing one of the biggest tech companies in the world has placed this at the heart of it’s apps.

Tooling: As we’ll see in a bit, the tooling around GraphQL sprouted very quickly, there are very mature tools and libraries for GraphQL available. Have a look at the GraphQL Awesome repository.

Standardized: Many companies release open source software, but GraphQL has gone a step further and has become a standard (in draft form currently). You can read the standard more in depth.
Standards are more likely to be adopted by other companies and the industry as a whole.

I’m Convinced GraphQL is Production Ready. Now What?

Now we know a little more about what makes up GraphQL. We also have a better understanding of its readiness for serious production usage. Let’s build an React / Node.js app demonstrating GraphQL in action.

No Secret Sauce

Let me be very clear: you do NOT need special libraries on the client side to make a GraphQL request. GraphQL is nothing more than POSTing a specific JSON object to an endpoint and receiving JSON in return. For example, this sample GraphQL is POST’d to our endpoint.

Houston, This is Apollo, There's no Problem.

The wonderful developers at Apollo have created a suite of amazing tools we’ll leverage to build our React frontend and Node.js backend. In fact, they provide GraphQL tools for more than just React and Node.js, but also Angular, Vanilla JS, Swift (iOS), and Android.

A library of tools we use to convert out GraphQL schema language into functions our ExpressJS server understands.

Countdown to App Lift Off

Without wasting anymore time, let’s get to work and start to build a simple app to demonstrate React, Node.js, and of course, GraphQL. For today, we’ll keep it simple and create a Contacts application and will allow us to add people to our Contacts and list them as well.

First Things, First

Before we get ahead of ourselves, let’s chart our course. We do this by creating our GraphQL schema. This will define the shape of the request and responses our GraphQL server will accept and return. Have a look at the following GraphQL schema for a Person.

type Person {
# The internal ID of the person, required
id: ID!
# First name, required
firstName: String!
# Last name, required
lastName: String!
# Age in years
age: Int
# Phone number of the person
phone: String
# Is the phone number a mobile number
isMobile: Boolean
# This person’s best friend
bestFriend: Person
}

It’s a simple schema for a person we might use to keep track of the contact information for a friend. Pretty simple. Now we just need two other items to define in our GraphQL schema: the input used to create / update a person and the operations our clients will call. First, let’s have a look at the input for our Person.

input PersonInput {
# The internal ID of the person
id: ID
# First name, required
firstName: String!
# Last name, required
lastName: String!
# Age in years
age: Int
# Phone number of the person
phone: String
# Is the phone number a mobile number
isMobile: Boolean
# The person’s best friend ID
bestFriend: ID
}

Hey, what gives?

It looks like we just took the Person type and used it for the input, you’re pretty much right. GraphQL treats input different from output as you may want to require certain input, but not output. For instance, look at the id. For the type or output, we require it, but for our input, we do not require it. Think about when we create a new person, we don’t yet know the ID which may be assigned by the database. When an id is present, we know this is an update instead of a create operation. In addition, bestFriend is just an ID for the input, but the type or response it is a full Person type.

The last definition we’ll define in our schema is the actual methods or operations the client will call to create, update, and list our contacts.

From this definition, you can see we have two query operations and one mutation operation. The two queries, person and people fetch a single person and a list of people respectively. The mutation operation allows us to create or update a person.

Now save those three schema definitions into one file called “schema.gql”. We’ll import it later when we setup our server.

A Solid Platform

Now we have our schema well defined, it’s time to assemble our Node.js / Express server. As I mentioned earlier, Apollo provides a middleware utility to work nicely with Express, but that’s the easy part. Before we set the app up, we need to talk about an important concept for Apollo GraphQL.

Resolvers

What are Resolvers? Glad you asked. Remember when I mentioned GraphQL doesn’t know how to talk to your database? It’s true. Each query, mutation, and type needs to know how to resolve the GraphQL request into an acceptable response. To do this, Apollo will require you to create an object that knows how to return the data requested.

Let’s take a look at what our resolvers for our schema would look like.

For simplicity, we are just going to hold our data in memory in a ‘people’ array. For a real app, you would use a data store of some kind.

If the resolvers look familiar, that’s good. Resolvers are nothing more than a JavaScript object with keys matching our schema. Since we are just using a simple JavaScript array as our datastore, we’ll use the index as the id of the person.

Apollo matches these resolvers we just defined with our schema. Now it knows how to handle each type of request. Even though we’ve just scratched the surface, you can see GraphQL Queries, Mutations, Resolvers, and Types at work.

Let me draw your attention to the Person resolver. By default, Apollo will just try to return the properties of an object as-is, but sometimes we need to give it some help or change what’s returned on the fly. Take a look at the bestFriend resolver. Since this one will return a Person type, we need to use the id of the bestFriend, look them up in the people array and return the entire person.

Keep in mind, Apollo will only fire off this bestFriend function if the client has requested to receive the bestFriend property.

Assembly Time

Now we have our schema defined in `schema.gql`, and our resolvers defined in `resolvers.js`, we need to put everything together to serve up our GraphQL. Here we define a simple Express app you can place in index.js of your project.

This may look a little complicated on surface, but in reality, it’s just pulling together your schema definition (typeDefs), matching it with your resolvers by using the makeExecutableSchema, then finally adding the GraphQL to the URL path /graphql. Now you can start the server with the command:

Go ahead and play around with some of the operations we defined. It feels good to have the backend up and running, doesn’t it? Let’s take a look at some simple React components and how they would communicate with our GraphQL backend.

Front Command Center

Now it’s time to demonstrate some React components leveraging this great Contacts API we’ve defined. Setting up a full frontend using Webpack, React Router, Redux and other elements is a little beyond the scope of this article, so we’re going to just show how Apollo fits into the picture.

First, let’s take a look at some top-level app code you’ll need to take advantage of Apollo’s React library in your components. This npm modules is called react-apollo.

In this simple example of an app, we are wrapping our App with the ApolloProvider Higher Order Component. This will set up much of the needed communication between the client and the GraphQL server.

Now let’s take a look at what it would look like to display a Person with ID of 10. This simple example below would automatically fire off the GraphQL query when the component mounted. The query is defined with the const query = gql` …. `; template literal. This query and the component for the PersonView are combined using the graphql library you see here.

This is a Higher Order Component to your Person component. This means Apollo will take of contacting the GraphQL server and when it’s received an answer, Apollo will inject those props into your component as

Next, let’s have a look at a Mutation as it’s a little different. In fact, the Query and the Mutation can live on the same React component, so let’s expand our previous example to update our person with a mutation.

Take a close look at this interesting piece of code. We’ve pulled in the compose utility so we can use it to combine multiple GraphQL operations around a single component.

We’ve also defined an update query to use the person update mutation we’ve defined in our schema. If you look towards the bottom of the code, you see we’ve created a wrapper function called submit. This submit gets passed as a prop into the Person component. From there we pass it as a prop into our PersonView component.

Our PersonView component could fire off an update to the person by simply calling the submit function much like this example here

Apollo would take the input to the submit function and pass it to the person mutation as the variable input.

You want to know something mind blowing?

When you fire off a mutation to update something like the Person type, Apollo automatically updates your local cache for the item. So everywhere your app uses the Person record, it will get automatically updated; you don’t have to do a thing on your end.

Last, let’s have a look at the code to display all the people in a table. In the following code sample, we have a simple HTML table displaying our list of people. Pay special attention to the loading property. This is a prop Apollo will set when it’s fetching this data, so you can show a spinner or some other informative UI message to the visitor.

Again, like before, we define our React component. Then our query using the gql tool to transform our template literal into a working GraphQL request. Finally, we tie them together with the graphql tool. Now when this component is mounted, the query will automatically fire and load the people we have stored in our backend.

Conclusion

As you’ve seen, GraphQL is a powerful suite of tools you can integrate into your React applications to supercharge the interaction with the API. Using Apollo makes it easy to add GraphQL to your React frontend and Node.js backend. Now is a great time to test out these new found skills you have in GraphQL. You could write a small app to play with the technology more, or unobtrusively included GraphGL into one of your existing API servers. Whichever way you choose to include GraphQL into your application stack, you’ll be happy you did.

About the Author

Shane Stillwell, author, speaker, and senior developer resides up north in chilly Duluth, Minnesota. Over the past fifteen years, when not shoveling snow, he's consulted for Under Armour, BrightCove, Meijer, and other top notch organizations. Shane specializes is in the realm of custom web application development using React, Node.js, and Docker. During this time he’s been able to hone his skills and happily shares them with anyone willing to listen. A family man that enjoys anything in the out of doors, you can find Shane most places around the web using @shanestillwell.