Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

W H Y ?

Slide 12

Slide 12 text

Application data management

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

$ 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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Decouple the clients and services

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

• 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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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.

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

C O M P O N E N T S

Slide 24

Slide 24 text

• 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

Slide 25

Slide 25 text

Building tools to improve the
 GraphQL developer experience

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

• 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

Slide 28

Slide 28 text

Focused on debugging, transparency, and simplicity

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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);

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

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