π£
π£
Apollo Caching and API Design
type Query {
posts: [Post]
authors: [Author]
...
}
type Author {
id: ID!
firstName: String
lastName: String
posts: [Post]
}
type Post {
id: ID!
title: String
author: Author
votes: Int
}
query postsForAuthor {
author(id: "1") {
id
firstName
lastName
posts {
id
title
}
}
}
{
"author": {
"id": "1",
"firstName": "Dave",
"lastName": "A",
"posts": [{
"id": "5",
"title": "GraphQL",
}]
}
}
mutation addPost {
addPost(input:{
authorId:"1",
title: "More!"
}) {
post {
id
title
}
}
}
{
"addPost": {
"post": {
"id": "6",
"title": "More!"
}
}
}
query postsForAuthor {
author(id: "1") {
id #### ALWAYS FETCH ID
firstName
lastName
posts {
id #### ALWAYS FETCH ID
title
}
}
}
query listOfAuthors {
id #### ALWAYS FETCH ID
firstName
lastName
}
π£
π£
π£
mutation changePost {
updatePost(input:{
id:"1",
title: "Update this!"
}) {
post {
id ### ALWAYS FETCH ID
title
}
}
}
π£
π£
π£
π£
query postsForAuthors {
author(id: "1") {
id
firstName
lastName
posts { ### NOT REMOVED
id
title
}
}
}
mutation removePost {
removePost(input:{
authorId:"1",
postId: "6"
}) {
post { # DATA FOR REMOVED RECORD
id
title
}
}
}
π£
π£
<Mutation
mutation={REMOVE_POST}
update={(cache, { data: { removePost } }) => {
const { todos } = cache.readQuery({ query: GET_POSTS });
cache.writeQuery({
query: GET_POSTS,
data: { posts: posts.filter((post) => post.id == removePost.post.id) }
});
}}
>
query postsForAuthors {
author(id: "1") {
id
firstName
lastName
posts {
id
title
}
}
}
mutation removePost {
addPost(input:{
authorId:"1",
title: "Sup"
}) {
post {
id
title
}
author {
id
posts { # NOW UPDATED!
id # GOTTA GET THOSE ID!
}
}
}
}
query postsForAuthors {
author(id: "1") {
id
firstName
lastName
posts {
id
title
votes # WE USE VOTES HERE
# BUT NOT ELSEWHERE
# SUBTLE BUG ALERT!
}
}
}
mutation addPost {
addPost(input:{
authorId:"1",
title: "Stuff"
}) {
post {
id
title
# DANGER NOT FETCHING FIELDS
# USED IN ANOTHER QUERY
}
author {
id
posts { # STILL REFTCH LIST
id # MEMBERSHIP
}
}
}
}
π£
π£
π£
query postsForAuthors {
author(id: "1") {
id
firstName
lastName
posts {
...allPostFields
}
}
}
# FRAGMENTS HELP KEEP CONSISTENCY
fragment allPostFields on Post {
id
title
voteCount
}
mutation removePost {
addPost(input:{
authorId:"1",
title: "Stuff"
}) {
post {
# NO ERRORS NOW!
...allPostFields
}
author {
id
posts {
id
}
}
}
}
π£
π£