import { Appear, Notes, Split, Image } from "mdx-deck"; import { CodeSurfer, Step, CodeSurferColumns, } from "code-surfer";
import { github, nightOwl } from "@code-surfer/themes";
export const theme = nightOwl;
Senior Frontend Developer @ Yolk AI 🍳
- i.t. automation for financial institutions, e.g. chatbot, knowledge base
- probably never had heard of us
- What/Why Apollo Local State 🤔
- My experience 😃
- My pros and cons ⚔️
- A quick-solution for the cons ☀️
- form wizard, built probably by many of you
-
prime candidate, not our flow editor
-
implemting a ui like this is tough, need state management lib
-
components need to share data
-
e.g. input something in one node here, another component needs to change
-
e.g. network calls would be expensive, user needs to do work without saving all of the time
-
complex single page apps which have a combination of remote data and local data are a great candidate for ALS
-
difficult problem but many many solutions
- e.g. redux, react state/context, flux
- apollo local state is one of those solutions
- react state is very primitive
- doesnt work at scale
- great for state held within a component
- different components need to know state of each other
- need to be updated when another component is updated
- in a fashionable and of course maintanable way
- Pre-req to Apollo Local State
- A GraphQL Javascript Client
- Query and Mutate Remote Data from a GraphQL API
- A Network Cache (important!)
- if you are building a frontend you are likely already usig graphql and also using apollo client
- apollo client lets you query and mutate remote data on a graphql api
- has a built-in cache which has enables some pretty awesome features
- e.g. blah blah blah
- this is how apollo client gives you a lot of nice features like different fetch policies
- do a request, its in the cache
- one part of the cache is updated,
- all components which are querying that part of the cache will be updated
- this is where apollo local state comes in
- instead of duplicating the cache/store where your client side state will live
- might as well use the same one amirite
- instead of bringing in another state management library like Redux so the Apollo cache can be a single source of truth.
- meaning your network cache is the same exact thing as your local state cache
- lets go into apollo local states pros and cons
- these are the big ones from my experience
- are some more on both sides that i dont mention
- my talk so I get to talk about what I want
- Typesafe
- Query/Mutations
- Schema
pro:
- data manipulations upon the local state cache are performed with mutations, something that previous GraphQL users already understand
- fragments
- lingo is the same
- One normalized cache
- Funded
- One ecosystem
- having one cache for both network/local is very powerful
- Staying within the Apollo ecosystem meant smooth integration with existing tools, meaning less overhead for developers.
- almost zero extra config if already using apollo client
- very similar to how you query/mutate remote data
- apollo dev tools
- Hard to test
- Boilerplate (e.g. resolvers)
- because one action per reducer, means mutations can have a lot of code
- a lot of code, means a lot of testing
- Skipping the config!
-
here is am example of editing a model that may appear in the cache
- an issue name, in the app, github
-
this data was likely loaded from the remote graphql api at some point
-
that means it is in the cache for us to manipulate
-
simple example just used to make the understanding of apollo local state easier
- probably would use something like react-state for this
-
define the mutation
-
looks similar to remote grapqhl api mutation
-
use enters new value in the input
-
client side mutation is run
-
updates the cache
-
which makes the queries on issue name run again
-
thus updating all parts of your app where issue name is
extend type Mutation {
# A mutation which edits the name on a Github Issue.
editGithubIssue(input: EditGithubIssueInput!): Boolean
}
input EditGithubIssueInput {
id: ID!
name: String!
}
- very familar to people who have worked with graphql apis
- notice the extend statement on the type from the server type
- apollo client will merge the schemas
- next the resolver which handles actually mutating the cache data
- Goes to show the dev experience here is lacking
- this is how to do it, straight from the docs
- Ts makes this worse but I havent wrote regular JS in almost two years
- just like ellen, i was disgusted
- repeat this for every mutation
- This was not as bad in redux
- Not much boilerplate
- Was easy to test
- in redux, you defined an action and wrote the resolver which:
- was usually small
- easily testable
- because one action per reducer, means mutations can have a lot of code
- way too much code which could go wrong or devs forgetting to do things
- to test this you need a fake store and perform fake mutation on it
- hard to test
- lots of use of external apis
After some 🤔 and many mutations ✍️ ...
- what we came up with which made the whole process a lot more simple
- we started to see some patterns
- assumption you are writing data in the same format you read it
- way less chance for mess ups
- more complex mutations that need data from elsewhere can opt-out
- became an even better experience
- very easy to test these reducers
Recap 📚
- Learned about Apollo Local State and how it relates to GraphQL/Apollo Client
- Used inspiration from Redux, e.t.c. to make the experience much better