
Relay FAQ: Facebook's Data-fetching Framework for React - btown
https://gist.github.com/wincent/598fa75e22bdfa44cf47?
======
wincent
I wrote the gist; happy to answer questions (although out and on my phone
right now so I won't be super fast).

~~~
iamartnez
A common problem in a service oriented architecture is needed to minimize the
amount of round trips to a particular service.

Example: To render a UI view, I need to fetch a list of friends, a list of
posts, and a list of notifications. All 3 of these data types (friends, posts,
notifications) have users associated with them. Instead of fetching users for
the 3 data types 3 separate times, I need to flatten that into a single call.
I end up with something like this:

    
    
      var [posts, friends, notifs] = yield [
        getPosts(),
        getFriends(),
        getNotifs()
      ]; // executes in parallel
    
      var userIDs = new Set();
      userIDs.addAll(posts.map(p => p.userID));
      userIDs.addAll(friends.map(f => f.userID));
      userIDs.addAll(notifs.map(n => n.userID));
    
      var users = yield getUsers(userIDs.toArray());
    
      return {posts, friends, notifs, users};
    

You can see where this gets cumbersome. I have to compose one of these for
every kind UI view at the root level. On the one hand it's very explicit and
the flow of data is very clear, but it also means relationships between data
are dupicated in more than one place (often many places).

Could GraphQL help with that scenario?

~~~
snissn
What language is that?

~~~
iamartnez
That's ES6 JavaScript (running on Node 0.11.15). We've already migrated most
of our production code to this and we're loving it!

If you like that kind of control flow, check out the library we wrote to do
it: [https://github.com/storehouse/engen](https://github.com/storehouse/engen)

~~~
jsprogrammer
Why not use let instead of var?

~~~
iamartnez
Only habit. We're so used to var. But yea, need to transition to let for most
things.

~~~
yoshuaw
I think migrating to const makes more sense. In practice only a few things
require to be mutated.

~~~
jsprogrammer
Didn't realize const was in. Will definitely be using it.

------
dragonshed
Much of this FAQ reminds me of a little-known library called Breeze.

BreezeJS is a stand-alone data library for SPAs which takes care of managing
the lifecycle of data objects; querying, fetching, caching is all taken care
of. Queries use OData by default, but implements a specific subset of the
query language that can rendered down and used against REST apis. Breeze also
provides server libraries for different stacks to easily integrate and get up
and running.

Granted the usecase of embedding declarative queries as part of a component
which gets composed along with other components+queries is unique to React,
but I speculate it wouldn't be too difficult to implement within Breeze.

All that said, it will be nice to see another rich-data management library to
compare and contrast. The days of painstakingly writing business objects in 34
places will end.

------
dustingetz
Would it be accurate to say that Relay's approach works best for component-
based apps (not React components, "component" in the more general sense) -
that is, the app is made up of a bunch of mostly separate components that
encapsulate their own state, like {Feed, Ads, Groups, Messaging, Photos,
Events, Minifeed}, which don't really share much state and don't require
central coordination?

~~~
wincent
Not really. It's true that those kinds of "components" will usually live on
their own routes, but there's nothing intrinsic to the framework that favors
that particular kind of app structure.

~~~
skrebbel
I'd like to phrase dustingetz' question slightly differently: if you're
building an app that does _not_ have multiple relatively independent parts as
dustin describes, does Relay still have a major advantage over what's
currently common? (i.e. if one page is only ever one "thing", how is it better
than just calling the right APIs from the router be done with it?)

------
javamonn
"Simplified server implementation: Rather than having a proliferation of end-
points (per action, per route), a single GraphQL endpoint can serve as a
facade for any number of underlying resources."

GraphQL sounds tremendously exciting.

------
dlau1
This looks incredible.

Especially excited at the idea of a single store. I've always had a little bit
of a beef with Flux when it came to interdependencies within stores.

I feel like one of the problems with react that is currently not well solved
is the integration of a client and server side router for a truly isomorphic
application. There have been quite a few implementations that rely on a single
om-like state that they serialize and deserialize to the client. Relay feels
like it would fit extremely well into this paradigm.

~~~
fattenap
Check out
[http://entrendipity.github.io/astarisx/](http://entrendipity.github.io/astarisx/)
. It uses a Single Source of Truth to accomplish what you're after.

------
city41
This looks very similar to a library I've been working on (live demo here for
webkit browsers:
[http://city41.github.io/bookends/demo.html](http://city41.github.io/bookends/demo.html)),
and it was inspired by a similar framework that is used at my former employer.

------
ndreckshage
Also, this is as interesting as React Native. And React Native is pretty
interesting.

------
ndreckshage
This is the biggest thing for JSON payload control since...JSON APIs became a
thing?

~~~
modarts
What's "JSON payload control" exactly?

~~~
ndreckshage
Confidence in returning the minimum to render a view. By default, without
having to worry about over / under fetching data. Not having to worry about
cleaning up endpoints when the needs of the consumer changes. A client that
requests exactly what it needs, rather than hitting an endpoint with
'something', is extremely efficient.

~~~
modarts
Great answer; thanks for the clarification!

------
phi16180
Here's the video introducing it at React.js conf:
[https://www.youtube.com/watch?v=9sc8Pyc51uU](https://www.youtube.com/watch?v=9sc8Pyc51uU)

------
xanderjanz
If you're interested in building GraphQL with Node+Mongo, checkout this github
project:
[https://github.com/lutherism/GraphNoQL](https://github.com/lutherism/GraphNoQL)

~~~
juliennakache
Wow! That was fast!

------
pwpwp
I am confused: why is data made available as props and not as state?

~~~
chacham15
This [https://github.com/uberVU/react-guide/blob/master/props-
vs-s...](https://github.com/uberVU/react-guide/blob/master/props-vs-state.md)
is a good explanation of the difference. But in short, it essentially comes
down to who can manipulate the data. If the component will manipulate it, then
it is state. On the other hand, if a difference source is going to be
manipulating it, then it should be a prop. In this case, the client side of
relay will be changing the data according to instruction from the server (e.g.
a new message arrived). Therefore, the state is being passed as a prop.

------
j_s
Does Facebook list browser requirements for all of this anywhere?
(Translation: can I use any of this at my day job?)

~~~
e1g
Relay is positioned as being complementary to React, and React itself
currently works on IE8+. There is talk of phasing out IE8 compatibility from
React (probably later this year), but as of today it works on IE8 perfectly
fine for us.

~~~
j_s
Thanks!

None of this tech requires much promotion since it's clearly the new hotness,
but there is a silent majority of developers that would appreciate knowing
when they can start paying attention professionally. Hopefully soon all
JavaScript projects will include a list of supported platforms alongside their
corner GitHub banner.

------
_wo6a
This is very interesting. I'm currently a little bit of the way through
solving some of the problems solved by Relay using an existing open source
stack, and I'm curious if anyone has any thoughts on how it would compare.
I've only skimmed the Relay video, and I haven't created a full React app yet,
so forgive me if I get something wrong.

First, for the framework-level handling of fetching all data before rendering,
where the data needed by each component is defined in each component, just
copy how it's done in react-router's async-data example [1], modified to
expect a hash of promises as in [2].

The promises return Backbone-Relational models [3]. You can model arbitrary
relations using Backbone-Relational, although many-to-many is apparently kind
of hacky (but just needs work to be seamless). It supports parsing REST API
responses with nested models and collections as related models. A REST API
generator like Flask-Restless [4] creates these responses with a single
efficient query.

You have the flexibility to either sync all models before rendering, or render
any component without all data already being fetched, and have it
automatically re-render when loaded.

Components subscribe and unsubscribe to model events at the proper points in
the component lifecycle using react-backbone-component.[5] I missed this and
wrote my own version [6] before I found it, but mine is cleaner, slightly more
featureful, and presents a simpler API.

Anyway, this requires some work to pull together, but I think it presents a
viable alternative that:

\- uses existing libraries that do one thing well and allows as much departure
from each elements of the architecture as you want

\- works with react-router, which is the shit

\- works with your existing REST API

Relay looks wonderful, but it's possible to build the abstractions that do
pretty much the same thing that support existing REST APIs.

[1] [https://github.com/rackt/react-
router/blob/master/examples/a...](https://github.com/rackt/react-
router/blob/master/examples/async-data/app.js#L121)

[2] [https://github.com/rackt/react-
router/wiki/Announcements](https://github.com/rackt/react-
router/wiki/Announcements)

[3] [http://backbonerelational.org/](http://backbonerelational.org/)

[4] [https://flask-restless.readthedocs.org/en/latest/](https://flask-
restless.readthedocs.org/en/latest/)

[5] [https://github.com/magalhas/backbone-react-
component](https://github.com/magalhas/backbone-react-component)

[6]
[https://gist.github.com/mwhite/f763c189f58de7af5d34](https://gist.github.com/mwhite/f763c189f58de7af5d34)

