Apollo + Graphql state management

apollo-boost 🔥

opensource community developers💔

Title Text

Who Am I

Usama Liaquat

Lead developer at Namshi

Developer at 5sd / Code Avenue

Graphql

What 

Why

GraphQL

{
    hero {
        name {
           friends {
                 name  
                   }  
             }        
         }

}
{
  "hero" : {
          "name" : "Madiha kamil",
          "friends" : [
                { "name": "Luis Averhoff" },
                { "name": "Sasha Meltser" },
                { "name": "Prashant Lakhera"},
                { "name": "Jigar Navadiya"}
        ]
    }
}

GraphQL is a query language for a API's and a runtime for fulfilling those queries with your existing data. 

Apollo Client 

The apollo client is designed to help you quickly build a UI that fetches data

with graphQL

export default graphql(gql`
  mutation submitRepository($repoFullName: String!) {
    submitRepository(repoFullName: $repoFullName) {
      createdAt
    }
  }
`)(props => (
  <button
    onClick={() => {
      // Mutate function passed via props
      props.mutate({
        variables: {
          repoFullName: "apollographql/apollo-client"
        }
      });
    }}
  >
    Click me
  </button>
));

Apollo Server

The apollo server is a library that focus on defining the shape of your data and how to fetch it

GraphQL :  The library is to build schema and to execute queries on that schema

Getting started apollo server ?

Apollo server building the most powerful and production ready GraphQL app easy.

const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type Query { hello: String }
`;

const resolvers = {
  Query: { hello: () => 'world' },
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen()
  .then(() => console.log('Server started! 🚀'));

What about Apollo state management ?  

import ApolloClient from "apollo-boost";
import { defaults, resolvers } from "./resolvers";

const client = new ApolloClient({
  uri: `https://nx9zvp49q7.lp.gql.zone/graphql`,
  clientState: {
    defaults,
    resolvers,
    typeDefs
  }
});

apollo-link-state allows you to store your local data inside the apollo cache alongside your remote data

Before 😕

yarn add  graphql  graphq-tag  apollo-client 

                    apollo-cache-inmemory  apollo-link-http  react-apollo

After 😍

yarn add  graphql  apollo-boost  react-apollo

Before 😕

import ApolloClient from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: new HttpLink({
    uri: 'https://nx9zvp49q7.lp.gql.zone/graphql'
  }),
});

After 😍

import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'https://nx9zvp49q7.lp.gql.zone/graphql'
});

Under the hood of Apollo boost

  • onError: Global error handling function
  • clientState: Local state management with Apollo
  • fetchOptions: Pass to your HTTP request

Simple auth with request

import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'https://nx9zvp49q7.lp.gql.zone/graphql',
  request: operation => {
    operation.setContext(context => ({
      headers: {
        ...context.headers,
        authorization: localStorage.getItem('token')
      }
    }));
  }
});

The Apollo Client experience

  • Declarative data fetching
  • Intelligent zero-config caching
  • Combine local and server data
  • Excellent developer's tools

Declarative data fetching

import { gql } from 'apollo-boost';

const GET_DOGS = gql`
  {
    dogs {
      id
      breed
      displayImage
    }
  }
`;

Declarative data fetching

const Dogs = () => (
  <Query query={GET_DOGS}>
    {({ loading, error, data }) => {
      if (loading) return <Fetching />;
      if (error) return <Error />;

      return data.dogs.map(dog => (
        <Dog key={dog.id} {...dog} />
      ));
    }}
  </Query>
);

The Apollo cache normalizes your data for you.

How do
we keep our data consistent?

Your cache key is __typename:id

Normalization

http://tiny.cc/s9omzy

Inspect the cache with apollo devtools ?

Query local data with
apollo-link-state! 🎉

2017: Separate stores, no cohesion

2018: One unified interface for all data

Mark local data with @client

const GET_DOG = gql`
  query getDogByBreed($breed: String!) {
    dog(breed: $breed) {
      images {
        url
        id
        isLiked @client
      }
    }
  }
`;
export const resolvers = {
  Image: { isLiked: () => false },
  Mutation: {
    toggleLikedPhoto: (_, { id }, { cache, getCacheKey }) => {
      const fragment = gql`
        fragment isLiked on Image {
          isLiked
        }
      `;
      const fragmentId = getCacheKey({ id, __typename: "Image" });
      const photo = cache.readFragment({ fragment, id: fragmentId });

      cache.writeData({
        id: fragmentId,
        data: { isLiked: !photo.isLiked }
      });

      return null;
    }
  }
};
import ApolloClient from 'apollo-boost';

const client = new ApolloClient({
  uri: 'https://nx9zvp49q7.lp.gql.zone/graphql',
  clientState: {
    resolvers,
    defaults,
    typeDefs,
  },
});

Add resolvers to Apollo Boost

const LIKE_PHOTO = gql`
  mutation toggleLikedPhoto($id: String!) {
    toggleLikedPhoto(id: $id) @client
  }
`;

Use the @client directive

export const DogWithLikes = ({ url, id }) => {
  return (
    <Mutation mutation={LIKE_PHOTO}>
      {toggleLike => (
        <View>
          <Image source={url} />
          <Heart onPress={toggleLike} />
        </View>
      )}
    </Mutation>
  );
};

Update local data with a mutation

Switching from Redux to Apollo Link State simplified how I interact with my codebase significantly, by allowing me to integrate my local state with GraphQL & Apollo.

Scott Tolinski, Level Up Tuts (@stolinski)

Client side schemas

const typeDefs = `
  type Todo {
    id: String
    message: String!
  }

  type Query {
    todo(id: String!): Todo
  }
`;

With GraphQL, we can unify developer tooling across the stack.

Empathy builds

better software. 😍

Github : Usamaliaquat123

Repo:  https://tinyurl.com/ybkw7ft9

Slides:  https://tinyurl.com/y8ps9s6j

Thanks 😍

Apollo + graphql state management

By Usama Liaquat

Apollo + graphql state management

  • 100