2. ● My company is awesome
● GraphQL, what and why
● How to transition
● Tips and gotchas
Outline
3. Working to connect every teacher, student and parent
In a study, text-message alerts to parents reduced course failures by 39% and
increased class attendance by 17%.
Over 20 million actively use Remind every month (70% of US public schools)
Over 3.6 billion messages delivered on Remind in 2016
4. Now: Engineering Manager on Engagement team at Remind
N-1 Led our Web platform and Client Infra team
N-2 Started React at Coursera
N-3 Academia
Turadg Aleahmad
9. ● Over-fetching for 5yr backwards compatibility
● Client-server misunderstandings (nullability, enums, Swagger lies, etc)
● Under-fetching (without getting a backend dev)
● Ad-hoc batching (“graph” queries in REST)
● Rails API monolith hard to break apart
Problems we faced
10. ● Every fetch declares exactly what it needs
● Schema is fully typed and enforced
● Client can batch whatever it likes
● Nested data parsing is well specified
● Lightweight graph resolver service abstracts away all the actual services
Why we adopted GraphQL
11. Apollo
● Developed by dedicated company
● Optimized for ease of use
● Builds on Redux
● Available now and trustable migration
path
● Will keep stealing from Relay
Choosing a stack
Relay
Used by Facebook
Optimized for performance
Heavier to adopt
Relay 1.0 was going to be replaced by
something very different, with no timeline
(Haven’t looked yet at Relay Modern)
14. Started as fast rewrite of an Angular app into React with vanilla Flux pattern.
(Summer 2015)
Backbone, with a store for almost every type. CurrentUser, GroupStore, …
No libraries, just a pattern. No constraints.
Lots of actions that were also blocking promises (shortcut).
Starting point
15. Had two data access patterns for components:
1. Store updates
2. Promise resolution
Add:
3. Apollo client
…without breaking the other two.
Goal
18. Isolated GraphQL component
Test out developer experience and operations
Chose a single form field to test read/write
Low traffic off in the settings page
Used react-apollo abstraction to contain entirely in component
19.
20.
21. Want all our existing data access to resolved by GraphQL
Had to maintain contract of the actions (Flux and promises)
But also update the Apollo state
GraphQL in legacy actions
22.
23.
24. Component queries updating legacy stores
Actions were now updating stores and Apollo
Pure GraphQL requests had to manually update stores (localUpdate)
We wanted a way to have legacy stores update when any relevant data came in
by GraphQL
watchQuery fires when any data underlying the query changes
25.
26. Some REST endpoints we haven’t migrated to GraphQL server yet
Authed User object tricky to move. For push data, no other option.
We don’t want to fetch redundantly so we bring that data into Apollo
Have to match the response structure for the query, including __typename
Adapting legacy data into Apollo
29. As components declare what they need, you need to track what you already
have.
dataIdFromObject is the cache key in Apollo’s part of the Redux store.
We ended up writing a lint rule to ensure that the key data is always queried
https://github.com/apollographql/eslint-plugin-graphql/pull/50
Cache keys
30.
31. HTTP response headers
GraphQL responds 200 if the resolver returns.
The resolver can gather a lot of errors.
Further complicated by network-level query batching.
Have to write logic for what you used to handle by HTTP error codes.
32.
33.
34. Mobile clients in the wild will continue to require REST
Don’t want to have multiple paths
We created middleware for REST on top of GraphQL
https://github.com/remind101/rest-graphql
REST client compatibility
35. ● Great with Apollo client
● Just rehydrate the Redux store
● All data needs are declared in visual components
● For security, make sure every request gets a fresh client instance
● Also make sure that instance does not have query batching (CPU leak)
Server rendering
36. ● Adopt in small steps
● Plan far ahead
● Get your schema right
● Be creative
Parting thoughts