Usama Liaquat
Senior software developer in ulcreative Softwares. Angular5 , RxJs , Electron guy
Apollo + Graphql state management
apollo-boost 🔥
opensource community developers💔
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
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
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 😍
By Usama Liaquat
Senior software developer in ulcreative Softwares. Angular5 , RxJs , Electron guy