Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL and Relay

Helielson
January 29, 2016

GraphQL and Relay

Concepts, Spec and how we are using it at jusbrasil.com.br

Helielson

January 29, 2016
Tweet

More Decks by Helielson

Other Decks in Programming

Transcript

  1. Definition GraphQL is a query language designed to build client

    applications by providing an intuitive and flexible syntax for describing their data requirements and interactions.
  2. REST problems - Multiple round trips to render single views

    - Receives unnecessary data - Payloads tend to grow over time for all clients
  3. - Code duplication - API changes with client need -

    Hard to scale with multiple clients - Hard to keep backwards compatibility Ad hoc endpoints (view oriented)
  4. How we think about data? - Not tables, joins or

    URIs - But: - Objects - Properties - Relationships - What, not How
  5. { post(id: 65) { title, votes, author { name, avatar

    } } } Hierarchical { "post": { "title": "Post title", "votes": 100, "author" { "name": "Didi", "avatar": "http://x.jpg" } } }
  6. Schema - Think as a Graph - Define structure of

    nodes (properties) - How they are connected
  7. Type System - Interface - Object - Enum - Union

    - List - Scalars: - String, Int, Boolean
  8. query { user(email: "[email protected]") { ...userInfo followers { ...userInfo }

    } } fragment userInfo on User { name, email lastPosts { ...somePostFrament } }
  9. fragment petInfo on Pet { petName, owner { name }

    … on Dog { noiseVolume: barkVolume } … on Cat { noiseVolume: meowVolume } }
  10. Open to optimizations - Batch - Cache - "DataLoader is

    the true" http://github.com/facebook/dataloader
  11. Network-GraphQL (how we are using) - Unify object definition -

    Unify loader definition - Helper for thrift-style relationships - Add an extra optimization layer - Auto extract selections from query
  12. Network-GraphQL (how we are using) - Define the schema based

    on jusbrasil-types - Rethinking data structure - english - relationships - building as we need - Based on network Thrift API
  13. What's coming next? - Open source movement - Improve data

    coverage - Provide authorization in schema (acl) - Mutation (done) - Object authorization - Field authorization
  14. A lot of trips between server and client /feed #

    get feed (documents ids) /documents/{id} # get a document /topics/{id} # get a topic Reuse the endpoint
  15. - How to fetch data - How to coordinate requests

    - How to coordinate writes - How to handle retries/errors - How to keep server/app in sync - How to update view with changes - How to cache data - How to keep that all in your head - How to …. - Your App What you had to think about:
  16. Focus on what matters most! Relay make easy for developers

    to focus on the product and forget about data access nuances
  17. // Story.js export default class Story extends React.Component { render()

    { var story = this.props.story; return ( <View> <Image uri={story.author.profilePicture.uri} /> <Text>{story.author.name}</Text> <Text>{story.text}</Text> </View> ); } }
  18. export class Story extends Component { … } export default

    Relay.createContainer(Story, { fragments: { story: () => Relay.QL` fragment on Story { author { name profilePicture { uri } } text } `, }, });
  19. export class Story extends React.Component { ... } export default

    Relay.createContainer(Story, { fragments: { story: () => Relay.QL` fragment on Story { author { ... } } `, }, }); Colocation
  20. export class NewsFeed extends Component { … } export default

    Relay.createContainer(NewsFeed, { fragments: { feed: () => Relay.QL` fragment on Feed { stories(first: $count) { // fetch viewer's stories edges { // traverse the graph node { ${Story.getFragment('story')} // compose child fragment } } } } `, }, });
  21. class FeedRoute extends Relay.Route { static routeName = "FeedRoute"; static

    queries = { feed: () => Relay.QL` query { userFeed(uid: $userID) } `, }; } var feedRoute = new FeedRoute({userID: '123'}); Query Routes
  22. export default Relay.createContainer(NewsFeed, { initialVariables: { count: 3 }, fragments:

    { feed: () => Relay.QL` fragment on Feed { stories(first: $count) { ... } } `, }, });
  23. class NewsFeed extends React.Component { render() { ... } loadMore()

    { var count = this.props.relay.variables.count; this.props.relay.setVariables({ count: count + 5, }); } }
  24. followers(first: Int, last: String) { edges { node // the

    actual follower object, cursor // node identifier in the edge }, pageInfo { hasNextPage, lastCursor } } Pagination: How it works?
  25. export default Relay.createContainer(Story, { fragments: { story: () => Relay.QL`

    fragment on Story { author { name followers(first: $limit) @include(if: $isDesktop) { ... } } text } `, }, }); Directives
  26. getMutation() { ... } getFatQuery() { ... } getConfigs() {

    ... } getVariables() { ... } Defining a mutation
  27. export default class LikePostMutation extends Relay.Mutation { getMutation() { ...

    } getVariables() { ... } getConfigs() { ... } getFatQuery() { ... } } Defining the mutation
  28. export class Story extends React.Component { handleEditPost() { const onFailure

    = () => {}; const onSuccess = () => {}; Relay.Store.commitUpdate(new LikePostMutation({ post: this.props.post, like: true }), {onFailure, onSuccess}); } } Sending the mutation
  29. interface Node { id: ID! } type Post extends Node

    { id: ID!, … // post fields } Object Tracking:
  30. - Server-side rendering support - React Router integration - Babel

    Plugin - Active development: - Subscription (live) on the work - Client state is being discussed Important Details
  31. - Work well with others tools - Flux, Redux, etc

    - Patterns are still emerging Not a silver bullet