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

Efficient Data Fetching with GraphQL and Relay

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →

Efficient Data Fetching with GraphQL and Relay

Avatar for Dan Schafer

Dan Schafer

July 22, 2015

More Decks by Dan Schafer

Other Decks in Programming

Transcript

  1. { id: 3500401, name: "Jing Chen", isViewerFriend: true, mutualFriends: {

    count: 195 }, profilePicture: { uri: "http://…", width: 50, height: 50 } }
  2. { id: 3500401, name: "Jing Chen", isViewerFriend: true, mutualFriends: {

    count: 195 }, profilePicture: { uri: "http://…", width: 50, height: 50 } }
  3. GraphQL { "node": { "id": "1572451031", "name": "Daniel Schafer" }

    } { node(id: 1572451031) { id name birthdate { month day } } }
  4. GraphQL { "node": { "id": "1572451031", "name": "Daniel Schafer", "birthdate":

    { "month": 1, "day": 17, } } } { node(id: 1572451031) { id name birthdate { month day } } }
  5. var FriendInfo = React.createClass({ render: function() { return ( <div>

    <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); GraphQL + React
  6. var FriendInfo = React.createClass({ statics: { queries: { } }

    render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); GraphQL + React
  7. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name mutualFriends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); GraphQL + React
  8. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name mutualFriends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); GraphQL + React
  9. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name mutualFriends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); GraphQL + React
  10. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name mutualFriends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); GraphQL + React
  11. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name mutualFriends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); GraphQL + React
  12. Composition var FriendListItem = React.createClass({ render: function() { return (

    <div> <ProfilePic user={this.props.user} /> <FriendInfo user={this.props.user} /> </div> ); } });
  13. Composition var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ?? ?? } `; } } }, render: function() { return ( <div> <ProfilePic user={this.props.user} /> <FriendInfo user={this.props.user} /> </div> ); } });
  14. Composition var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ${ProfilePic.getQuery(‘user’)}, ${FriendInfo.getQuery(‘user’)} } `; } } }, render: function() { return ( <div> <ProfilePic user={this.props.user} /> <FriendInfo user={this.props.user} /> </div> ); } });
  15. Lifecycle var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ${ProfilePic.getQuery('user')} ${FriendInfo.getQuery('user')} } `; } } } }); Static View
  16. Lifecycle var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ${ProfilePic.getQuery('user')} ${FriendInfo.getQuery('user')} } `; } } } }); Static View FriendListItem
  17. Lifecycle { node(id: 1572451031) { name mutualFriends { count },

    profilePicture { uri width height } } } Query Server ew
  18. Lifecycle { "node": { name: "Daniel Schafer", mutualFriends: { count:

    195 }, profilePicture: { uri: "http://...", width: 50, height: 50 } } } y Server Data
  19. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name mutualFriends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutualFriends.count} mutual friends</span> </div> ); } }); Response Shape
  20. Pagination { "1572451031": { "name": "Daniel Schafer" } } {

    node(id: 1572451031) { name friends { name } } }
  21. Pagination { "1572451031": { "name": "Daniel Schafer", "friends": [ {

    "name": "Jing Chen" }, { "name": "Lee Byron" }, { "name": "Nick Schrock" }, { "name": "Joe Savona" } ] } } { node(id: 1572451031) { name friends { name } } }
  22. Pagination { "1572451031": { "name": "Daniel Schafer", "friends": [ {

    "name": "Jing Chen" }, { "name": "Lee Byron" }, { "name": "Nick Schrock" }, { "name": "Joe Savona" } ] } } { node(id: 1572451031) { name friends(first: 2) { name } } }
  23. Pagination { "1572451031": { "name": "Daniel Schafer", "friends": [ {

    "name": "Jing Chen" }, { "name": "Lee Byron" } ] } } { node(id: 1572451031) { name friends(first: 2) { name } } }
  24. Pagination { "1572451031": { "name": "Daniel Schafer", "friends": [ {

    "name": "Jing Chen" }, { "name": "Lee Byron" } ] } } { node(id: 1572451031) { name friends(first: 2 offset: 2) { name } } }
  25. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": [ {

    "name": "Jing Chen" }, { "name": "Lee Byron" } ] } } { node(id: 1572451031) { name friends(first: 2) { name } } }
  26. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": [ {

    "name": "Jing Chen" }, { "name": "Lee Byron" } ] } } { node(id: 1572451031) { name friends(first: 2) { edges { node { name } cursor } } } }
  27. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2) { edges { node { name } cursor } } } }
  28. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2 after: 4802170) { edges { node { name } cursor } } } }
  29. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2 after: 4802170) { edges { node { name } cursor } } } } { "1572451031": { "name": "Daniel Schafer", "friends": { "edges": [ { "node": { "name": "Nick Schrock" }, "cursor": "37000641" }, { "node": { "name": "Joe Savona" }, "cursor": "842472" } ] } } }
  30. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2 after: 842472) { edges { node { name } cursor } } } } { "1572451031": { "name": "Daniel Schafer", "friends": { "edges": [ { "node": { "name": "Nick Schrock" }, "cursor": "37000641" }, { "node": { "name": "Joe Savona" }, "cursor": "842472" } ] } } }
  31. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2 after: 842472) { edges { node { name } cursor } } } } { "1572451031": { "name": "Daniel Schafer", "friends": { "edges": [] } } }
  32. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2) { edges { node { name } cursor } } } }
  33. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2) { edges { node { name } cursor } pageInfo { hasNextPage } } } } { "1572451031": { "name": "Daniel Schafer", "friends": { "edges": [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } }
  34. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2) { edges { node { name } cursor } pageInfo { hasNextPage } } } } { "1572451031": { "name": "Daniel Schafer", "friends": { "edges": [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ], "pageInfo": { "hasNextPage": true }, } }
  35. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2 after: 4802170) { edges { node { name } cursor } pageInfo { hasNextPage } } } } { "1572451031": { "name": "Daniel Schafer", "friends": { "edges": [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ], "pageInfo": { "hasNextPage": true }, } }
  36. Cursors { "1572451031": { "name": "Daniel Schafer", "friends": { "edges":

    [ { "node": { "name": "Jing Chen" }, "cursor": "3500401" }, { "node": { "name": "Lee Byron" }, "cursor": "4802170" } ] } } } { node(id: 1572451031) { name friends(first: 2 after: 4802170) { edges { node { name } cursor } pageInfo { hasNextPage } } } } { "1572451031": { "name": "Daniel Schafer", "friends": { "edges": [ { "node": { "name": "Nick Schrock" }, "cursor": "37000641" }, { "node": { "name": "Joe Savona" }, "cursor": "842472" } ], "pageInfo": { "hasNextPage": false }, } }
  37. Connections in Relay var FriendList = React.createClass({ render: function() {

    return ( <div> { this.props.viewer.friends.map( function(user) { return <FriendListItem user={user} />; } ) } </div> ); } });
  38. Connections in Relay var FriendList = React.createClass({ statics: { queries:

    { viewer: function() { return graphql` Viewer { friends { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, render: function() { ... } });
  39. Connections in Relay var FriendList = React.createClass({ statics: { queries:

    { viewer: function() { return graphql` Viewer { friends(first: 10) { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, render: function() { ... } });
  40. Connections in Relay var FriendList = React.createClass({ statics: { queries:

    { viewer: function() { return graphql` Viewer { friends(first: 10) { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, render: function() { ... } });
  41. Connections in Relay var FriendList = React.createClass({ statics: { queryParams:

    {count: 10}, queries: { viewer: function(params) { return graphql` Viewer { friends(first: ${params.count}) { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, render: function() { ... } });
  42. Connections in Relay var FriendList = React.createClass({ statics: { queryParams:

    {count: 10}, queries: { viewer: function(params) { return graphql` Viewer { friends(first: ${params.count}) { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, onScrollLoad: function() { this.setQueryParams({count: this.queryParams.count + 5}); }, render: function() { ... } });