How to partially update a large GraphQL model in cache after mutation?

Viewed 12

For this question, the following schema is a simplified description of the situation:

type CartItem {
  id:ID!
  description:String!
  qty:Int
  price:Float
}

type Cart {
  createdAt:DateTime
  updatedAt:Datetime

  items:[CartItems!]
}

type Mutation {
  removeCartItem(itemId:ID!):Cart
}

(Again, this is providing the most basic use case I can think of for this question.)

When removing an item from the cart, it is expected that the Cart value stored in cache will reflect the new updated state, thus the entire cart is returned.

import { useQuery, useMutation, gql } from '@apollo/client';

const CART_QUERY = gql`query GetCart {
  cart {
    createdAt
    updatedAt

    items {
      id
      description
      qty
      price
    }
  }
}`;

const REMOVE_ITEM_MUTATION = gql`mutation RemoveCartItem($itemId:ID!) {
  removeCartItem(itemId:$itemId) {
    createdAt
    updatedAt

    items {
      id
      description
      qty
      price
    }
  }
}`;


function CartDisplay() {
  const { loading, data:{ cart } } = useQuery(CART_QUERY);
  const [ removeCartItem ] = useMutation(REMOVE_ITEM_MUTATION);

  const handleDeleteItem = itemId => {
    removeCartItem({ variables: { itemId } });
  }

  return cart?.items?.length ? cart.items.map(cartItem => (
    <CartItemCard key={ cardItem.id }
      cardItem={ cardItem }
      onDelete={ handleDeleteItem }
    />
  )) : (
    <div>No items in cart</div>
  );
}

Because GraphQL updates the Cart when it is mutated, the useQuery triggers a component update with the updated value. However, the entire Cart is fetched!

How can the mutation return only the parts that should be updated, in this case, tell the cache to remove the item from the array? Do I have to manually update the cache when the mutation is successful? What about optimistic updates?

In other words, what should the mutation return in order to only update what needs to be updated and not the entire graph data; is that even possible?

0 Answers
Related