Unleashing the power of GraphQL and React
slides.com/gerardsans | @gerardsans
Google Developer Expert
Master of Ceremonies
Blogger
Trainer
Community Leader
850
1K
GraphQL
GraphQL co-authors
Lee Byron
Nick Schrock
Dan Schafer
GraphQL Timeline
2012
GraphQL created at Facebook
Support Mobile Native Teams
2016
GitHub announces GraphQL API
New GraphQL website
First GraphQL Summit
GraphQL First
2017
Apollo Client 1.0
GraphQL Europe
Launchpad
GraphQL Explore
www.graphql.com
graphql.org
Apollo Optics
launchpad.graphql.com
Implementations
Query Language
// GET '/graphql'
{
user(name: "gsans") {
twitter
}
}
// result
{
"user": {
"twitter": "@gerardsans"
}
}
GraphQL Server
source: blog
Who is using it?
Solution Architecture
demo
GraphQL Schema
Type System
- Scalar Types: Int, Float, String, Boolean, ID
- Object Types: Question
- Entry points: Query, Mutation, Subscription
Schema Syntax
- Nullable: String, Question
- Non-nullable: String!, Question!
- Arrays: [String], [Question]
Schema (1/2)
schema {
query: Query,
mutation: Mutation
}
type Query {
allQuestions(skip: Int, take: Int): [Question!]!
}
type Question {
id: ID!
body: String!
}
Schema (2/2)
schema {
query: Query,
mutation: Mutation
}
type Mutation {
createQuestion(body: String!): Question
}
GraphiQL
demo
Apollo Client
GraphQL Server
source: blog
Dependencies
- JavaScript client for GraphQL (apollo-client)
- Analyses queries and results to keep data cached
- API to run queries and mutations (react-apollo)
- Template literal (graphql-tag)
Setup
// client.js
import ApolloClient, { createNetworkInterface } from 'apollo-client'
const networkInterface = createNetworkInterface({
uri: 'https://api.graph.cool',
dataIdFromObject: record => record.id, // will be used by caching
})
export const client = new ApolloClient({ networkInterface })
Bootstrap
// app.js
import { ApolloProvider } from 'react-apollo'
let combinedReducer = combineReducers({
filter,
apollo: client.reducer(),
})
const store = compose(
applyMiddleware(client.middleware())
)(createStore)(combinedReducer)
render(
<ApolloProvider store={store} client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
)
Main APIs
- query
- mutate
- updateQueries (reducer)
query
// List.js
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'
const withQuestions = graphql(
gql`query questions {
allQuestion {
id body
}
}`, {
props: ({ ownProps, data }) => {
if (data.loading) return { userLoading: true }
if (data.error) return { hasErrors: true }
return {
list: data.allQuestions,
}
}
})
mutate
// App.js
const withAddQuestion = graphql(
gql`mutation addQuestion($body: String!) {
createQuestion(body: $body) {
id body
}
}`,
{
props: ({ ownProps, mutate }) => ({
addQuestion(text) {
return mutate({
variables: { body: text },
updateQueries: {
todos: (state, { mutationResult }) => {
return {
allQuestions: [...state.allQuestions,
mutationResult.data.createQuestion
],
}
...
Subscriptions
GraphQL Server
source: blog
Dependencies
- Server side package to connect with the pub/sub system (graphql-subscriptions)
- WebSocket client + server (subscriptions-transport-ws)
Setup
// client.ts
import { SubscriptionClient, addGraphQLSubscriptions } from 'subscriptions-transport-ws'
const wsClient = new SubscriptionClient('wss://subscriptions.graph.cool/v1', {
reconnect: true,
})
const networkInterface = ...
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
networkInterface,
wsClient
)
export const client = new ApolloClient({
networkInterface: networkInterfaceWithSubscriptions,
})
Subscription Schema
schema {
query: Query,
mutation: Mutation,
subscription: Subscription
}
type Question {
id: ID!
body: String!
}
type Subscription {
Question(filter: {
mutation_in: [CREATED]
}) {
node {
id
body
}
}
}
Subscribe
// QuestionList.js
const withSubscription = graphql(QUESTIONS_QUERY,
{
props: ({ data: { subscribeToMore } }) => ({
subscribeToNewQuestions() {
return subscribeToMore({
document: QUESTIONS_SUBSCRIPTION,
updateQuery: (state, { subscriptionData }) => {
const newQuestion = subscriptionData.data.Question.node
if (!isDuplicate(newQuestion.id, state.allQuestions)) {
return update(state, {
allQuestions: {
$push: [newQuestion],
},
})
}
},
})
},
}),
},
)
Why use GraphQL?
Some reasons
- Declarative
- De-coupled from storage
- Validated and structured
- Facilitates Collaboration
- Super fast
Thanks!
Дякую
Unleashing the power of GraphQL and React
By Gerard Sans
Unleashing the power of GraphQL and React
GraphQL is awesome! After only a year it has got a lot of attention from the community. Many implementations have emerged and it’s just getting better. Is GraphQL right for you? Is it a query language or runtime? In this talk I am going to take you from 0 to hero. ;)
- 3,571