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. 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
  2. Client Server MongoDB Minimongo DDP / WebSocket Players.insert({ name: "Bob",

    score: 10 }); Players.find({ score: { $gt: 5 } });
  3. Semantic data with identity Lists of endpoints Stateful client-side caching

    Independent requests Declarative data requirements Imperative data fetches
  4. 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
  5. React Angular Swift Android Go Python Java Ruby Any backend,

    any client, any language GraphQL Scala
  6. 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
  7. 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
  8. $ 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
  9. 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
  10. • 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
  11. 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.
  12. 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
  13. • 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
  14. 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
  15. • 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
  16. const observable = client.watchQuery({ query, variables }); const subscription =

    observable.subscribe({ next(result) { }, error(error) { }, }); subscription.unsubscribe(); Returns Observable<GraphQLResult>
  17. import { ApolloClient } from 'apollo-client'; import { Provider }

    from 'apollo-react'; const client = new ApolloClient(); ReactDOM.render( <Provider client={client}> <RootComponent /> </Provider>, rootElement )
  18. 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);
  19. 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