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

Martijn Walraven, Meteor, Amsterdam — Building Reactive GraphQL Apps With Apollo

Martijn Walraven, Meteor, Amsterdam — Building Reactive GraphQL Apps With Apollo

Martijn Walraven, Meteor, Amsterdam — Building Reactive GraphQL Apps With Apollo

In this talk, I’ll introduce our efforts to design a reactive system to automatically re-run GraphQL queries when the underlying data changes. You will see how to make the collaborative parts of your app update in real time with little extra code, how to integrate with a SQL database or REST API, and how this works in concert with GraphQL’s best features to simplify your app’s data management while being predictable and maintainable.

React Amsterdam

April 21, 2016
Tweet

More Decks by React Amsterdam

Other Decks in Technology

Transcript

  1. Building Reactive GraphQL
    Apps with Apollo
    Martijn Walraven
    Core Developer, Meteor Development Group
    React Amsterdam 2016

    View full-size slide

  2. D A T A S T A C K
    • Client-side cache (Minimongo)
    • DDP / WebSockets
    • Methods and publications
    • Database driver
    • React/Angular/Blaze
    • Routing
    • Client-side reactivity
    V I E W L A Y E R
    B U I L D T O O L
    • EcmaScript
    • Mobile container
    • Hot code push
    • Deployment

    View full-size slide

  3. Client
    Server
    MongoDB
    Minimongo
    DDP / WebSocket
    Players.insert({ name: "Bob", score: 10 });
    Players.find({ score: { $gt: 5 } });

    View full-size slide

  4. Semantic data with
    identity
    Lists of endpoints
    Stateful client-side
    caching
    Independent requests
    Declarative data
    requirements
    Imperative data fetches

    View full-size slide

  5. D A T A S T A C K
    V I E W L A Y E R
    B U I L D T O O L

    View full-size slide

  6. React
    Angular
    Swift
    Android
    Go
    Python
    Java
    Ruby
    Any backend, any client, any language
    GraphQL
    Scala

    View full-size slide

  7. Application data management

    View full-size slide

  8. C L I E N T
    S E R V E R
    F E A T U R E A P I S
    Android
    Desktop iOS
    Endpoints

    View full-size slide

  9. C L I E N T
    S E R V E R
    F E A T U R E A P I S
    Android
    Desktop iOS
    Endpoints

    View full-size slide

  10. $ rake routes | wc -l
    655
    latest GET /latest(.:format) list#latest {:format=>/(json|html)/}
    category_latest GET /c/:category/l/latest(.:format) list#category_latest
    category_none_latest GET /c/:category/none/l/latest(.:format) list#category_none_latest
    parent_category_category_latest GET /c/:parent_category/:category/l/latest(.:format) list#parent_category_category_latest
    unread GET /unread(.:format) list#unread {:format=>/(json|html)/}
    category_unread GET /c/:category/l/unread(.:format) list#category_unread
    category_none_unread GET /c/:category/none/l/unread(.:format) list#category_none_unread
    parent_category_category_unread GET /c/:parent_category/:category/l/unread(.:format) list#parent_category_category_unread
    new GET /new(.:format) list#new {:format=>/(json|html)/}
    category_new GET /c/:category/l/new(.:format) list#category_new
    category_none_new GET /c/:category/none/l/new(.:format) list#category_none_new
    parent_category_category_new GET /c/:parent_category/:category/l/new(.:format) list#parent_category_category_new
    read GET /read(.:format) list#read {:format=>/(json|html)/}
    category_read GET /c/:category/l/read(.:format) list#category_read
    category_none_read GET /c/:category/none/l/read(.:format) list#category_none_read
    parent_category_category_read GET /c/:parent_category/:category/l/read(.:format) list#parent_category_category_read
    posted GET /posted(.:format) list#posted {:format=>/(json|html)/}
    category_posted GET /c/:category/l/posted(.:format) list#category_posted
    category_none_posted GET /c/:category/none/l/posted(.:format) list#category_none_posted
    parent_category_category_posted GET /c/:parent_category/:category/l/posted(.:format) list#parent_category_category_posted
    bookmarks GET /bookmarks(.:format) list#bookmarks {:format=>/(json|html)/}
    category_bookmarks GET /c/:category/l/bookmarks(.:format) list#category_bookmarks
    category_none_bookmarks GET /c/:category/none/l/bookmarks(.:format) list#category_none_bookmarks
    parent_category_category_bookmarks GET /c/:parent_category/:category/l/bookmarks(.:format) list#parent_category_category_bookmarks
    B A C K E N D F O R F R O N T - E N D

    View full-size slide

  11. Lists Image processing Accounts
    C L I E N T
    S E R V E R
    M I C R O S E R V I C E S
    Android
    Desktop iOS

    View full-size slide

  12. Decouple the clients and services

    View full-size slide

  13. We need an application-
    level query language
    Meteor: MongoDB Apollo: GraphQL

    View full-size slide

  14. • Nested query language
    • The query maps directly onto the
    shape of the response
    • Individual objects are resolved via
    requests to a backend data store
    Learn more at:
    • graphql.org (screenshot to the right)
    • medium.com/apollo-stack
    G R A P H Q L C R A S H C O U R S E

    View full-size slide

  15. A R C H I T E C T U R E

    View full-size slide

  16. Cordova
    Chrome React Native
    Data Cache Translation code
    Microservices Databases External APIs
    C L I E N T
    S E R V E R
    Apollo Server
    + Native iOS, Android, etc.

    View full-size slide

  17. Microservices
    C L I E N T
    S E R V E R
    Apollo Server
    User Interface
    Store
    C L I E N T
    Query Manager Mutations
    1. UI passes data requirements to client
    2. Queries diffed against existing stored data
    3. Minimized query sent to server
    4. Data aggregated from backend services
    5. Result returned to client
    6. Client updates store
    7. Result is delivered to the UI
    L I F E C Y C L E O F A Q U E R Y

    View full-size slide

  18. C O M P O N E N T S

    View full-size slide

  19. • GraphQL tools from Facebook and the
    rest of the community:
    • GraphQL-JS, DataLoader, and a whole
    host of community tools on the server
    • Relay
    We’re standing on the shoulders of
    giants, and combining that with our
    experience building Meteor.
    P R I O R A R T
    GraphQL-JS Graphene
    Relay Sangria

    View full-size slide

  20. Building tools to improve the

    GraphQL developer experience

    View full-size slide

  21. A P O L L O S E R V E R
    Microservice Microservice
    Translation code
    Apollo Server
    GraphQL execution
    type Person {
    name: String
    age: Int
    }
    Declarative schema
    (params) => {
    ...
    return data
    }
    • Runs as a GraphQL translation layer on
    top of your existing backends
    • The most natural way to write a
    GraphQL-JS server
    In progress at apollostack/graphql-tools
    and apollostack/apollo-starter-kit
    User Interface

    View full-size slide

  22. • Relay-like client built on Redux that can
    be incrementally adopted in any
    application
    • Will support pagination, optimistic UI,
    reactivity, and more
    In progress at apollostack/apollo-client
    A P O L L O C L I E N T
    Apollo Server
    User Interface
    Refetching and
    optimistic UI
    Apollo Client
    Normalized object
    store
    query {
    pet(id: 5) {
    name
    species
    }
    }
    Query fetching

    View full-size slide

  23. Focused on debugging,
    transparency, and simplicity

    View full-size slide

  24. const observable = client.watchQuery({ query, variables });
    const subscription = observable.subscribe({
    next(result) {
    },
    error(error) {
    },
    });
    subscription.unsubscribe();
    Returns Observable

    View full-size slide

  25. import { ApolloClient } from 'apollo-client';
    import { Provider } from 'apollo-react';
    const client = new ApolloClient();
    ReactDOM.render(


    ,
    rootElement
    )

    View full-size slide

  26. function mapQueriesToProps({ watchQuery, ownProps, state }) {
    return {
    category: watchQuery({
    query: `
    query getCategory($categoryId: Int!) {
    category(id: $categoryId) {
    name
    color
    }
    }
    `,
    variables: {
    categoryId: 5,
    },
    forceFetch: false,
    returnPartialData: true,
    })
    }
    }
    const CategoryContainer = connect({
    mapQueriesToProps,
    })(Category);

    View full-size slide

  27. Lists Image processing Accounts
    C L I E N T
    S E R V E R
    R E A C T I V E G R A P H Q L
    Apollo Server
    Data cache Invalidations

    View full-size slide

  28. @stubailo @UriGoldshtein
    @helferjs @martijnwalraven @debergalis
    Please get involved!
    medium.com/apollo-stack
    github.com/apollostack
    @apollostack
    You?

    View full-size slide