slides.com/gerardsans | @gerardsans
Spoken at 64 events in 23 countries
900
1.2K
GraphQL created at Facebook
React is released
React Native is released
GraphQL is open sourced
Relay Classic is open sourced
New GraphQL website graphql.org
First GraphQL Summit
GitHub announces GraphQL API
Relay Modern 1.0
Apollo Client 2.0
npm install --global graphcool graphcool init server
graphcool deploy graphcool console
// project.graphcool
type Todo @model {
id: ID! @isUnique
text: String!
complete: Boolean!
}
Apollo
Cache
Apollo
Link
const query = gql`query AllTodos {
allTodoes { id text complete }
}`;
const data = store.readQuery({ query });
const newTodo = {
id: createTodo.id,
text: input.value,
complete: false,
__typename: "Todo"
};
store.writeQuery({
query,
data: {
allTodoes: [...data.allTodoes, newTodo],
},
});
import { ApolloLink } from 'apollo-link';
import { createHttpLink } from 'apollo-link-http';
const httpLink = new HttpLink({ uri: URI });
const authLink = new ApolloLink((operation, forward) => {
const token = localStorage.getItem('authtoken');
if (token) {
operation.setContext({
headers: { Authorization: token }
});
}
return forward(operation);
})
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
source: blog
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
export const client = new ApolloClient({
link: new HttpLink({ uri: URI}),
cache: new InMemoryCache()
});
// index.js
import { ApolloProvider } from 'react-apollo';
import { client } from './client';
ReactDOM.render(
<ApolloProvider client={client}>
<App/>
</ApolloProvider>,
document.getElementById('root')
);
registerServiceWorker();
schema {
query: Query,
mutation: Mutation
}
type Todo {
id: ID!
text: String!
complete: Boolean!
}
type Query {
allTodoes(skip: Int, take: Int): [Todo!]!
}
const TODOS = gql`
query todos {
allTodoes { id text complete }
}`
const withTodos = graphql(TODOS, {
props: ({ ownProps, data }) => {
if (data.loading) return { loading: true }
if (data.error) return { hasErrors: true }
return {
todos: data.allTodoes,
}
},
})
const withAddTodo = graphql(gql`
mutation addTodo($text: String!) {
createTodo(text: $text, complete: false) { id text complete }
}`, {
props: ({ ownProps, mutate }) => ({
addTodo (text) {
return mutate({
variables: { text },
update: (store, { data: { createTodo } }) => {
const data = store.readQuery({ query: TODOS });
data.allTodoes.push(createTodo);
store.writeQuery({ query: TODOS, data });
},
})
},
}),
})
source: blog
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
export const client = new ApolloClient({
link: setupLink(),
cache: new InMemoryCache()
});
function setupLink() {
const httpLink = new HttpLink({ uri: URI });
const wsLink = new WebSocketLink({
uri: URI_WS,
options: { reconnect: true }
});
const isSubscription = ({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind==='OperationDefinition' && operation==='subscription';
}
const link = split(
isSubscription,
/* if true use */ wsLink,
/* otherwise */ httpSecured,
);
return link;
}
schema {
subscription: Subscription
}
type Mutation {
createTodo(text: String!, complete: Boolean!): Todo
deleteTodo(id: ID!): Todo
}
type Subscription {
Todo(filter: [CREATED, UPDATED, DELETED]): {
mutation: [CREATED, UPDATED, DELETED]
node: Todo
updatedFields: [String!]
previousValues: Todo
}
}
// app.component.ts
query.subscribeToMore({
document: gql`
subscription {
Todo(filter: { mutation_in: [CREATED] }) {
node { id complete text }
}
}
`,
updateQuery: (state, { subscriptionData }) => {
...
}
updateQuery: (state, { subscriptionData }) => {
const {node} = subscriptionData.data.Todo;
if (!state.allTodoes.find(todo => todo.id === node.id)) {
state.allTodoes.push(node);
}
return {
allTodoes: todos
}
}
gsans/todo-apollo-v2-react