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

2015

Open sourced

First Specification

GraphQL.js

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

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

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