React Relay GraphQL — Name a better trio

We’ve been on a forked version of Relay v8 for a couple years. While the new versions had some neat features, nothing really compelled us to upgrade until now. Relay v11 (the one with hooks) is the biggest release since Relay Modern & it’s amazing. Aside from hooks, it lets us use React’s Suspense API instead of the render props pattern, allows for fine-grain control of query invalidation, and provides patterns for avoiding waterfall queries. While we’ve been able to clean up a bunch of our code, there have also been a few sharp edges during the migration. Let’s explore.

Partial Data and Client Fields


Image by Aaron Ortbals
Image by Aaron Ortbals

GraphQL is great. Every GraphQL endpoint agrees to speak the same language of {data, errors} and that makes communication between servers easy. Now suppose two public APIs both speak GraphQL; what advantages can we leverage? Packages like graphql-tools make it easy to merge and stitch schemas together, which allows teams to build out separate parts of their subschemas via join and union functionality. But what about 3rd party schemas that have their own authentication, rate limiting, and errors? For example, take a look at GitHub’s GraphQL API. Wouldn’t it be great if you could nest GitHub’s endpoint in your own…


Scaling is relative. When Uber builds a scalable metric service, they build a proprietary database to resolve their queries. When Facebook scales a live feed, they build it to support millions of connected clients. This post is for the rest of us. Subscriptions in GraphQL have taken a back seat and it’s my goal to change that.

The most popular subscription client is abandonware and uses an insecure, inefficient protocol. That means those of us who want to build a real-time app are forced to roll our own. So if you have dreams of hitting 10,000 connected clients, but you’re…


Photo by paolo candelo

Nobody likes a callback. It’s like a modern day equivalent of a GOTO statement. But how can we replace those pesky ones like click handlers? Chances are, you’ve refactored all all the easy ones into async/await statements, but there are still those pesky holdouts like DOM events, WebSockets, event emitters, and any other stream-like object. Sure, we could turn those into Observables, but turning 1 callback into 3 doesn’t seem like much of an improvement. If I can promisify a function, why can’t I iterable-ify an event stream? The answer is the new 2018 async iterables, and since it was…


Back in late 2016 I wrote an article called GraphQL: Tips after a year in production. Since then, GraphQL started offering native subscriptions, Relay got so good you could replace Redux with Relay Modern, and I learned a few neat tricks along the way. I’ve also made a bunch of mistakes. Looking back on my GraphQL journey, here’s what I’d change.

1. Use a DataLoader from the get go

DataLoader is a small cache that is beautiful in its simplicity. Instead of caching the entirety of the GraphQL response, it caches database queries to be used in resolve functions. I put off implementing it in my app for…


Get it? Cuz they’re errors... and you throw & catch ‘em …nevermind

Click here to share this article on LinkedIn »

Recently, I screwed up and it resulted in a client getting a white screen when they used our app. Like most apps, we have an initial GraphQL query that fetches a ton, including a list of all your notifications. One of those notifications referenced a field that no longer existed in the database (oops!). The result? GraphQL was a champ and sent both data and errors to the client. But the client, well it completely ignored the data because it handled the response as an error. In hindsight, that was pretty…


It’s been almost 2 years since I wrote Replacing Relay with Redux. Since then, Relay added subscriptions, a build-time compiler, a sensible mutations API, and a game-changing client schema. That puts me in an awkward position. On the one hand, we JavaScript developers get a bad wrap for declaring technology as antiquated the moment something new comes along; but on the other hand, COOL NEW TECH! So with that said, Redux is out and Relay is in. I’m serious. Stop laughing.

Credit to Keith Pitt

The Business Case

Too much boilerplate, team members never documenting their action creator APIs, the ebbing battle of connecting to smart containers…


Subscriptions are really hard. That’s what makes them fun. It’s been a few months since GraphQL & Relay have supported them, and still examples are sparse. The worst part? The ones that do exist use patterns that will give you a headache if you try to implement them in your largescale app. Trust me.

After a whole lot of trial and error, I finally came across a pattern that scales linearly with your app. Hopefully, it’ll keep you from suffering as you embark on real-timeifying your app.

Some Background

The holy grail is a page where every piece of domain state updates…


I finally added Relay Modern to my production build and I gotta say… I dig it. When Relay Classic was first released, I poked a lot of fun at it and even made my own client cache (with redux & subscriptions). The new version beautifully shuts me up. It’s 5x smaller, has a vastly improved mutations API, reduces runtime complexity (thanks to babel + no diffing), is decoupled from React, and best of all: it has subscriptions.

Unfortunately, being a new library, there are a lot of questions left for the community to solve:

  • How do I pass the environment


Recently, I built out billing and invoicing functionality for our small, open-source SaaS app (look out world, we got ourselves a business model!). The added functionality expanded the codebase by something like 45% and errors crept in like gophers to a carrot patch. Now, we’re already pretty good about reactively handling errors. We use redux-middleware to send the error & redux state to Sentry, which grabs our sourcemaps & pings us on our Slack channel. But with billing, I want to catch the error before it happens… because refunds are embarrassing. Unfortunately, unit testing a database has always been a…

Matt Krick

Building the future of work

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store