Relay is a JavaScript library developed by Facebook that provides a framework for fetching and managing data for React applications. It uses GraphQL to allow clients to request specific data from an API in a declarative way. Relay handles data fetching, caching, normalization of responses, and passing the data as props to React components. Some key aspects of Relay include its use of containers to fetch data and translate GraphQL responses to JSON, its separation of remote and local data storage, and its composable architecture. While Relay speeds up development and keeps applications flexible, it also has some limitations as an early-stage project such as lack of documentation and examples for some use cases.
2. A LITTLE ABOUT BROOKE
SHAMELESS SELF PROMOTION
• Full stack developer at MetaLab and Robot Overlord
• Come see me for stickers and buttons after the talk 😉
• Organizes a few meetups
• Leaving the country in February, so giving a few talks before then
• Have been using Relay “professionally” since October 2015
• ~6 weeks after the initial technical preview was open-sourced
• Maintain awesome-relay, but honestly there’s not a ton written about Relay yet (repo will grow when there is more)
3. ONCE UPON A TIME…
VALUE PROPOSITION
• GraphQL + Relay version
• Took roughly a day
• Built a GraphQL type and tested it
• “Can we have a RESTful version for the old API?”
• Marty + REST version
• Took the most of the remainder of the week
• Had to build a custom route, controller, presenter, and serializer…
• …and then write tests for everything above
4. REACT + GRAPHQL + HELPERS = RELAY
WHAT WE’RE GOING TO COVER
• Why another front-end framework?
• A brief React refresher
• GraphQL
• Relay
• Closing thoughts
• Q&A
6. THINGS WORK, SO WHY BOTHER
LEARNING ANOTHER FRAMEWORK?
ANOTHER
FRAMEWORK?
7. DEVELOPER HAPPINESS IS IMPORTANT
BECAUSE FUN!
• It can’t be overstated as an important factor in long-term project success
• It’s fun to learn new things, be on the leading edge, &c
• It’s fun to contribute back to young project, or even open an Issue on the repo
• Removing boilerplate helps us get more done faster, which makes us feel good!
8. INDIVIDUAL AND INDUSTRY PROGRESS ARE IMPORTANT
BECAUSE PROGRESS!
• Otherwise our jobs would still involve writing FORTRAN on punch cards
• Open progress as a collective profession gets more eyes than internal solutions
9. EXPERIMENTING WITH NEW WAYS OF DOING THINGS IS IMPORTANT
BECAUSE NEW IDEAS!
• It might not end up being The One True Way, but it still a progression towards The
Next Big Thing
11. RELAY ISN’T GOING TO DISAPPEAR
BECAUSE FACEBOOK!
• Relay is Facebook backed
• Not disappearing any time soon
• Tied to the future of other tech, like React Native
13. EFFICIENTLY SYNCING DATA IS HARD
THE PROBLEM
• Generally, we need a way to read from and write to a server
• Projects start simple: a single RESTful endpoint can describe what’s on the page
• But eventually…
• Pages start to require data from multiple resources
• Different pages need different attributes from the same resource
15. WRITE A CUSTOM ENDPOINT FOR EACH USE CASE
EXISTING SOLUTIONS
• Write a custom API endpoint for each use case
• No over- or under-fetching (if you’re willing to put in the time)
• Doesn’t scale: time consuming; brittle; confusing
16. THE CANONICALLY RESTFUL WAY
EXISTING SOLUTIONS
• Write general RESTful endpoints for each resource
• Can use multiple queries to load data for several resources
• Often get less data than you need (under-fetching)
• Therefore can need multiple requests
• Often get more data than you need (over-fetching)
• Requests are larger than they need to be (inefficient)
17. PRE-FETCH EVERYTHING THAT THE USER MIGHT WANT
`
• Prefetch all of the data that the user might want on initial page load
• Inefficient (serious over-fetching) & poor performance
EXISTING SOLUTIONS
18. WHAT IF THE CLIENT CONTROLLED THE RESPONSE SHAPE?
THERE MUST BE A BETTER WAY
• Wouldn’t it be nice if we could…
• ask the server for specific information, ad hoc
• compose queries
• nest queries to mirror the UI’s nesting
• Facebook has a pretty popular website, and make frequent changes
• Updating a RESTful API would not keep up
• Explored a few solutions; settled on their GraphQL
• Netflix and Cognitect have come up with similar solutions
• Falcor
• The Om Next data resolver + Datomic
21. I’M GOING TO MOVE SOMEWHAT QUICKLY, OTHERWISE
STOP ME IF SOMETHING IS UNCLEAR
22. MORE THAN “THE V IN MVC”
PHILOSOPHY
• A functional approach
• Limit & control state
• Prefer keeping your data unchanged (immutable)
• Isolate any changing (mutable) data
• Components are functions that take props and return a chunk of Virtual DOM
• Declarative (“what”) > imperative (“how”)
• Data flow
• Of course, DRY
23. JS OBJECT UPDATES ARE MUCH FASTER THAN A BROWSER’S RENDERER
VIRTUAL DOM
• Instead of manipulating the DOM directly, we update a JSON representation it
• Can then diff the DOM, and make focused changes
• This makes re-rendering extremely fast
• We only get real DOM changes
when we need then
• Get multiple changes at once
(no flickering in and out)
• HTML & JSX are trees, so parents
“own” their children
24. WHO PUT HTML IN MY JS?
JSX
• Handy HTML-like syntax that compiles down to pure JS
• Can mix and match with HTML elements (more or less)
• Pass arguments as “props”
• Nested elements are “props.children”
26. ROLL YOUR OWN HTML TAGS
• Can write custom components for your display logic
• Just assign a name to the JSX (or plain JS) from previous slide
• Take props, and render plain HTML
COMPONENTS
29. SINCE ALL SCHEMAS ARE TECHNICALLY GRAPHS…
IDEOLOGY
• “REST gives you data per resource, so let’s try something else”
• Being RESTless(?) is developer heresy
• One endpoint to rule them all; usually /grahql
• Request only what you need
• Let the server figure out how
• Want JSON to express relationships between objects, but get duplication
• So, dedup nodes that have multiple connections
• Graphs are strictly more expressive than relational schemas
• Can rewrite any relational structure as a graph
30. “I WANT SOME DATA THAT LOOKS LIKE THIS“
DECLARATIVE SYNTAX
31. GETTING CONTRACTS INTO YOUR APPLICATION
TYPES
• User definable “shapes” or “structs”
• Fields be required or optional
• Enforce data consistency
• Catch bugs early
• Keep the database clean
• Doubles as documentation
34. THE “PUT/POST/DELETE/SIDE-EFFECT” OF GRAPHQL
MUTATIONS
• “Mutations” are how you change (“mutate”) the world outside of the FE app
• Update a field in the database
• Send an email
• Fire the missiles
• Set up like a function (arguments -> graph fragment)
36. ORDER A SIDE OF DOCS WITH YOUR API
INTROSPECTION
• Can construct a regular query to get metadata
• First-class!
• The schema itself
• the whole thing, or just a portion
• Descriptions of fields
• Descriptions and fields on types
• Descriptions and fields on mutations
• Which fields are required
• What the fragments it can return are
• &c.
39. IT’S PRETTY NEW™
RELAY
• React was publicly released at the end of May, 2013
• Relay’s technical preview made available in mid-August, 2015
• Facebook has been using parts of it internally for a while (~2 years?)
• They have also been using GraphQL with iOS applications for a while, too
41. MAGICAL BOXES TO HANDLE YOUR COMPONENT’S DATA NEEDS
CONTAINERS
• Wraps a “plain” component (HOC)
• Fetches data from the server
• Translates GraphQL to JSON
• Composable (KILLER FEATURE)
45. SEPARATION OF REMOTE AND LOCAL DATA
TRULY LOCAL DATA
• Relay really wants its client and server stores to be consistent
• If some data is not going to be synced to the server, it doesn’t belonging the graph
• Store such data in the React component state
• ex. partially filled form fields, locked buttons, which tab is visible, &c
• One store for Relay’s synced (“remote”) data, and several for purely local data
46. IT’S LIKE THEY WERE NEVER HERE
EPHEMERAL DATA
• Relay doesn’t really directly handle temporary data
• For example, let’s say the we want a temporary token that will not be persisted
• We have three options:
• Plain REST
• Plain GraphQL
• Fake it with a null node
47. FAKE IT ‘TILL THEY MAKE IT
THE NULL NODE KLUDGE
• Create an attribute on the User type node that returns null by default (initial query)
• Mutation to create the token
• Input: {userID: “PF8bxC7R51”}
• Output: {user { id: “PF8bxC7R51”, token: “i3g7BrhwHb” }}
• ie: works as normal
• This data probably doesn’t “belong” on the user, but it’s a convenient location
• If you refresh the page, you’ll need to go through the mutation again
48. PRETTY GREAT, BUT IT’S NOT ALL KITTENS AND RAINBOWS
PROS AND CONS
� Speeds up development
� Keeps things flexible
� Fun to use
� Very active repo
� Smart people working on it
� Feels like the future
� It’s (very) early days
� Documentation “could be better”
� Some unintuitive naming
� Few complete examples
� Bugs are sometimes the framework
� Doesn't handle local data