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

Data-fetching in React applications with Relay & GraphQL

Data-fetching in React applications with Relay & GraphQL

Marc-Andre Giroux

August 10, 2016
Tweet

More Decks by Marc-Andre Giroux

Other Decks in Programming

Transcript

  1. Let’s fetch that using ad-hoc endpoints ? /shop_cart_page /shop_cart_page?include=images /shop_cart_page_with_images?num_images=2

    /shop_cart_page_single_prices_and_descriptions_version1.2 /shop_cart_page_with_prices_and_descriptions_but_no_images 11 op_cart_page_with_prices_and_descriptions_and_images_but_only_one_300
  2. 12

  3. Query { myShop { name location { city address }

    products(orderby: PRICE) { name price } } } 16
  4. Response { “myShop” { “name”: “My Kool Shop”, “location”: {

    “city”: “Montreal”, “address”: “5333 Avenue Casgrain”, }, “products”: [{ “name”: “A Chair”, “price”: 10000 }, { “name”: “A Table”, “price”: 20000 }] } } 17
  5. Type System { myShop { name location { city address

    } products(orderby: PRICE) { name price } } } type QueryRoot { myShop: Shop } 18
  6. Type System enum ProductOrderEnum { PRICE, POPULARITY, ALPHABETICAL } type

    Shop { name: String location: Address products(orderby: OrderEnum): [Product] } { { myShop { name location { city address } products(orderby: POPULARITY) { name price } } } 19
  7. Type System type Address { city: String address: String }

    { { myShop { name location { city address } products(orderby: POPULARITY) { name price } } } 20
  8. Type System type Product { name: String price: Int }

    { { myShop { name location { city address } products(orderby: POPULARITY) { name price } } } 21
  9. Fragments { { myShop { name …locationFragment } } fragment

    locationFragment on Shop { location { city address } } 22
  10. Step 1: Making sense out of fragments { fragments: {

    image: () => Relay.QL` fragment on Image { url } `, }, 33
  11. Relay.QL (transformed) { fragments: { image: function image() { return

    function () { return { children: [{ fieldName: 'url', kind: 'Field', metadata: {}, type: 'String' }, { fieldName: 'id', kind: 'Field', metadata: { isGenerated: true, isRequisite: true }, type: 'ID' }], id: _reactRelay2.default.QL.__id(), kind: 'Fragment', metadata: {}, name: 'ProductImage_ImageRelayQL', type: 'Image' }; }(); } 35
  12. Step 2: Query diff ( The Store ) { RelayRecord

    Store • Client Side Cache • Normalized / Flattened Store 36
  13. Step 2: Query diff { fragments: { product: () =>

    Relay.QL` fragment on Product { name image { url } } `, }, 37
  14. Step 2: Query diff { fragments: { product: () =>

    Relay.QL` fragment on Product { name description image { url } } `, }, 38
  15. Step 2: Query diff { fragments: { product: () =>

    Relay.QL` fragment on Product { description } `, }, 39
  16. Step 2: Query diff { fragments: { product: () =>

    Relay.QL` fragment on Product { description } `, }, 40
  17. Step 3: Split Deferred queries { fragments: { product: ()

    => Relay.QL` fragment on Product { name description ${Images.getFragment('product').defer()}} } `, }, 41
  18. { myShop { name location { city address } products(orderby:

    PRICE) { name price } } } Final step: Printing { 46
  19. Mutations { class AddProductMutation extends Relay.Mutation { getMutation() { return

    Relay.QL`mutation { addProduct }`; } getVariables() { return { productName: this.props.product.name }; } getFatQuery() { … } getConfigs() { … } getOptimisticResponse() { … } } 48