exploring relay land
TRANSCRIPT
Exploring Relay-land
Stefano Masini @stefanomasini
Relay
• Automatic fetching of data, no more Ajax
• Colocation of queries and code
• Caching
• Good for API mashup
• Why not?
A new beginning
• How to fetch data from the server?
• How to write data to the server?
• How to handle URL routing?
• How to manage application (UI) state?
• How to propagate server push notifications?
Size of libraries
LOC - *.js in github project as of Feb 2016
0 K
20 K
40 K
60 K
80 K
100 K
React Relay GraphQL ReactRouter
Redux
Popularity of libraries
# stars in github project as of Feb 2016
0 K
8 K
16 K
24 K
32 K
40 K
React Relay GraphQL ReactRouter
Redux
Stars per Line Of Code
AKA what's the smartest idea out there? :-)
React Relay GraphQL ReactRouter
Redux
Topics
• How to fetch data from the server?
• How to write data to the server?
• How to handle URL routing?
• How to manage application (UI) state?
• How to propagate server push notifications?
GraphQL
• GOALS:
• Space efficient (on the wire)
• Computationally efficient (server side)
GraphQL
DEMO
GraphQL is a type systemUser
Site Site
Project Project Project
User Type
Site Type
Project Type
SitesOfUser Type
ProjectsOfSite Type
Edges
Edges
Node
Node
Node
Relay enhanced Type System
User
Site Site
Project Project Project
User Type
Site Type
SitesOfUser Type
Project Type
ProjectsOfSite Type
Relay caching (UI)
User X Site A Project 1 Project 2
Relay cache
React view
Server
Schemalet schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: 'RootQueryType', fields: () => ({ node: nodeField, loggedUser: { type: UserType, description: 'The logged user', resolve: (_, _, {rootValue: {loggedUser}}) => loggedUser, }, }) }), });
The User Typelet UserType = new GraphQLObjectType({ name: 'User', interfaces: [nodeInterface], fields: () => ({ id: globalIdField('User', user => user.id), node: nodeField, sites: { type: UsersInSiteConnection, description: 'All sites the logged user has access to', resolve: (user, args, {rootValue: {db}}) => connectionFromPromisedArray( db.getSitesForAUser(user), args ), }, }) });
Querying with RESTUser
Site Site
Project Project Project
/user/14/all_my_sites
SELECT * FROM users LEFT JOIN sites LEFT JOIN projects WHERE ...
GraphQL is like an ORMUser
Site Site
so, beware!
query { user(userId: "14") { sites { ... } }}
GraphQL is like an ORMUser
Site Site
Project Project Project
so, beware!
query { user(userId: "14") { sites { projects { ... } } }}
GraphQL is like an ORMUser
Site Site
Project Project Project
so, beware!
resolve(...)
resolve(...)
SELECT * FROM sites WHERE ...
SELECT * FROM projects WHERE ...
n x
Topics
• How to fetch data from the server?
• How to write data to the server?
• How to handle URL routing?
• How to manage application (UI) state?
• How to propagate server push notifications?
MutationsServer
Client
"Fat query"
Topics
• How to fetch data from the server?
• How to write data to the server?
• How to handle URL routing?
• How to manage application (UI) state?
• How to propagate server push notifications?
@relayContainer({ fragments: { user: () => Relay.QL` fragment on User { firstName, lastName, } `, }, }) class UserFullName extends React.Component { render() { return <p> {this.props.user.firstName} {this.props.user.lastName} </p>; } }
Rendering in Relay
Query ConfigurationRelay Container
Rendering in Relay
Component
Rendering in React-Router/user/14/settings
/ <Application>
user/14 <User>
settings <Settings>
/ Q RC <Application>
user/14 Q RC <User>
Relay + Router NAIVE/user/14/settings
settings Q RC <Settings>
Smart Root Container
/ RC <Application>
user/14 RC <User>
react-router-relay/user/14/settings
settings RC <Settings>
Topics
• How to fetch data from the server?
• How to write data to the server?
• How to handle URL routing?
• How to manage application (UI) state?
• How to propagate server push notifications?
Relay + ReduxRelay
data storeRedux
data store
• Site Name • Projects in a Site
• Dialog (open/close) • New project form
Edit existing project form???
Topics
• How to fetch data from the server?
• How to write data to the server?
• How to handle URL routing?
• How to manage application (UI) state?
• How to propagate server push notifications?
Keeping clients in sync
Server
Client
Cache
Client
Cache
Client
Cache
AKA: Live Queries
Subscriptions*
• GraphQL "subscription" operator
• Modeled after "events"
• Client must register/deregister
• Server must fire the right events in the right places
* yet to come, as of Feb 2016
I like Relay and GraphQL
• Modeling this way is fun
• It Just Makes Sense®
• It scales well
RELAY IS
AWESOMEbut...
Limitations*
• Poor error handling
• ORM-like, hard to optimize DB access
• Root queries
• Subscriptions
* as of Feb 2016
Relay is COMPLEX
Is you app COMPLEX too?
YES
Give it a try!
NO
Wanna learn?
Not today, thanks
Stay with REST and Redux
YES
Thanks!
@stefanomasini
video and slides