Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Apollo Client Cache

kobayang
October 10, 2019

Apollo Client Cache

kobayang

October 10, 2019
Tweet

More Decks by kobayang

Other Decks in Technology

Transcript

  1. ©2018 Wantedly, Inc.
    Apollo Client Cache
    meguro.es
    2019.10.10 - Naoki Kobayashi

    View Slide

  2. ©2018 Wantedly, Inc.
    Naoki Kobayashi
    GitHub: @kobayang
    Twitter: @kbys_02
    I’m an Frontend Engineer @Wantedly

    View Slide

  3. ©2018 Wantedly, Inc. https://blog.apollographql.com/introducing-the-apollo-graphql-platform-8ef34bb269e5
    cache

    View Slide

  4. ©2018 Wantedly, Inc.
    { Declare GraphQL Query
    Use Query to fetch data
    const TodoContainer = () => {
    const {
    data, loading, error
    } = useQuery(todosQuery);
    const todos = data ? data.todos : [];
    }
    const todosQuery = gql`
    query TodosQuery {
    todos {
    id
    title
    }
    }
    `;

    View Slide

  5. ©2018 Wantedly, Inc.
    Agenda
    • Apollo Client ͷ Cache ͸͍ͭߦΘΕΔ͔
    • ͲͷΑ͏ʹCacheͷߋ৽Λߦ͏͔
    • ͲΜͳσʔλ͕Cacheʹೖ͍ͬͯΔ͔
    • Cacheͷߋ৽ͷ࠷దԽ

    View Slide

  6. ©2018 Wantedly, Inc.
    Fetch Data Flow
    User Interface
    Fetch
    Cache
    3FRVFTUUP
    UIFTFSWFS
    .PVOUPSVTFSBDUJPO
    USJHHFSTGFUDI
    Apollo Server
    3FBEDBDIF

    View Slide

  7. ©2018 Wantedly, Inc.
    Prefetching Data
    https://www.apollographql.com/docs/react/performance/performance/
    onMouseOver Ͱ query ΛಡࠐΉ
    LinkઌͰ͸ಉ͡ΫΤϦΛಡࠐΉͱ
    Cache͕ώοτ͢ΔͨΊɺ
    Loadingͳ͠ͰData͕࢖͑Δ

    View Slide

  8. ©2018 Wantedly, Inc.
    Local State Management
    https://www.apollographql.com/docs/react/performance/performance/
    • CacheΛར༻ͯ͠LocalͷStateΛѻ͑Δ
    • @client directive Λ Query/Mutation ʹ

    ͚ͭΔ͜ͱͰऔಘઌ͕ϩʔΧϧʹͳΔ
    # local-schema.grpahql
    extend type Todo {
    done: Boolean!
    }
    // apollo.ts
    const resolvers: Resolvers = {
    Todo: {
    done(todo: TodoFragment) {
    return todo.done || false;
    },
    },
    };
    const todoFragment = gql`
    fragment TodoFragment on Todo {
    id
    title
    done @client
    }
    `;

    View Slide

  9. ©2018 Wantedly, Inc.
    InMemoryCache
    https://medium.com/expedia-group-tech/creating-your-own-apollo-cache-for-perf-and-profit-8f786849e5f6
    • ApolloClientͷΩϟογϡͷσϑΥϧτ࣮૷
    • Ωϟογϡ͢ΔࡍʹσʔλΛਖ਼نԽ͢Δ(Normalize)

    View Slide

  10. ©2018 Wantedly, Inc.
    Mutation Data Flow
    User Interface
    Mutation
    Apollo Server
    Cache
    3FRVFTUUPUIFTFSWFS
    VTFSBDUJPO
    USJHHFSTNVUBUJPO
    4UPSFDIBOHFT
    ESJWFT6*

    View Slide

  11. ©2018 Wantedly, Inc.
    Mutation Data Flow
    User Interface
    Mutation
    Apollo Server
    Cache
    3FRVFTUUPUIFTFSWFS
    VTFSBDUJPO
    USJHHFSTNVUBUJPO
    4UPSFDIBOHFT
    ESJWFT6*
    ࣮૷͢Δඞཁ͕͋Δ

    View Slide

  12. ©2018 Wantedly, Inc.
    ྫ: Todoͷ௥Ճ
    BEE5PEP.VUBUJPO
    UPEPT2VFSZ
    const todosQuery = gql`
    query TodosQuery {
    todos {
    id
    title
    }
    }
    `;

    View Slide

  13. ©2018 Wantedly, Inc.
    ྫ: refetchQueries
    const addTodoMutation = gql`
    mutation AddTodoMutation($title: String!) {
    addTodo(title: $title) {
    id
    title
    }
    }
    `;
    const [addTodo] = useMutation(addTodoMutation, {
    refetchQueries: [{ query: todosQuery }],
    });
    Cache
    3FGFUDI
    4FSWFS3FTQPOTF

    View Slide

  14. ©2018 Wantedly, Inc.
    ྫ: update
    const [addTodo] = useMutation(addTodoMutation, {
    update: (cache, { data }) => {
    const cachedQuery = cache.readQuery({ query: todosQuery });
    if (!cachedQuery || !data) {
    throw new Error();
    }
    const todos = cachedQuery.todos;
    cache.writeQuery({
    query: todosQuery,
    data: { todos: todos.concat([data.addTodo]) },
    });
    },
    });
    4FSWFS3FTQPOTF
    Cache

    View Slide

  15. ©2018 Wantedly, Inc.
    ΩϟογϡΛ೷͍ͯΈΔ
    Apollo Client Developer Tools: Ωϟογϡͷத਎Λ֬ೝͰ͖Δ

    View Slide

  16. ©2018 Wantedly, Inc.
    dataIdFromObject
    https://github.com/apollographql/apollo-client/blob/22a450aace/packages/apollo-cache-inmemory/src/inMemoryCache.ts

    View Slide

  17. ©2018 Wantedly, Inc.
    readFragment
    const data = client.readFragment({
    id: "Todo:1",
    fragment: todoFragment,
    });
    console.log(data);
    // => { id: 1, title: "ൃදࢿྉΛ࡞Δ", __typename: "Todo" }

    View Slide

  18. ©2018 Wantedly, Inc.
    id͕ͳ͍৔߹
    • ROOT_QUERY.todos.0 ͷΑ͏ʹ 

    ROOT_QUERY ʹඥ͍ͮͯΩϟογϡ͞ΕΔ
    const todosQuery = gql`
    query TodosQuery {
    todos {
    title
    }
    }
    `;

    View Slide

  19. ©2018 Wantedly, Inc.
    id͕ͳ͍৔߹
    • ࣮͸readFragmentͰऔಘͰ͖Δ
    const data = client.readFragment({
    id: “ROOT_QUERY.todos.0”,
    fragment: todoFragment,
    });
    console.log(data);
    // => { title: "ൃදࢿྉΛ࡞Δ", __typename: "Todo" }

    View Slide

  20. ©2018 Wantedly, Inc.
    Mutation Data Flowʢ࠶ܝʣ
    User Interface
    Mutation
    Apollo Server
    Cache
    3FRVFTUUPUIFTFSWFS
    VTFSBDUJPO
    USJHHFSTNVUBUJPO
    4UPSFDIBOHFT
    ESJWFT6*

    View Slide

  21. ©2018 Wantedly, Inc.
    Optimistic Response
    Mutation
    Apollo Server
    Cache
    User Interface
    Optimistic Response

    View Slide

  22. ©2018 Wantedly, Inc.
    Optimistic Response
    Mutation ͷҾ਺ʹ௥Ճ
    optimisticResponse: vars => ({
    addTodo: {
    id: "-1",
    title: vars.title,
    __typename: "Todo",
    },
    }),
    update: (cache, { data }) => {
    console.log("update", data);
    //…
    }
    update͸mutation࣮ߦ࣌ͱߋ৽࣌ʹ
    2ճݺ͹ΕΔ

    View Slide

  23. ©2018 Wantedly, Inc.
    Optimistic Response
    ApolloCache removeOptimistic Ͱ
    optimisticResponseͷΩϟογϡ͸࡟আ͞ΕΔ
    https://github.com/apollographql/apollo-client/blob/22a450aace/packages/apollo-cache-inmemory/src/inMemoryCache.ts#L251

    View Slide

  24. ©2018 Wantedly, Inc.
    ·ͱΊ
    • Apollo Clientʹ͸Ωϟογϡͷ࢓૊Έ͕͋Γ

    Fetchͨ͠σʔλΛਖ਼نԽͯ͠Ωϟογϡ͍ͯ͠Δ

    • Mutation࣌͸ɺঢ়گʹ߹Θͤͯ refetchQueries, update,
    optimisticResponse Λ࣮૷ͯ͠ΩϟογϡΛߋ৽ͤ͞Δඞཁ͕͋Δ

    • ΩϟογϡΛҙࣝ͢Δ͜ͱͰύϑΥʔϚϯεΛ޲্ͤ͞Δ͜ͱ͕Ͱ͖Δ

    View Slide