Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable customization of cache normalization behavior. #5443

Merged
merged 24 commits into from
Oct 21, 2019

Conversation

benjamn
Copy link
Member

@benjamn benjamn commented Oct 11, 2019

Still a work in progress; expanded description coming soon.

In our What's new in Apollo Client 2.6 blog post, we promised:

  • The standard apollo-cache-inmemory cache implementation promises to normalize your data, to enable efficient cache updates and repeated cache reads. However, not all data benefits from normalization, and the logic for deciding whether separate objects should be normalized together varies across use cases. Future versions of the Apollo Client cache will unify several related features—dataIdFromObject, the @connection directive, and cacheRedirects—so Apollo developers can implement specialized normalization logic, or even disable normalization for certain queries.

This pull request implements (most of) those promises already, and some other related improvements are on the way. As an example, it should be possible for the Apollo Client 3.0 cache to implement local state as part of this new configuration API, allowing us to remove/unify much of the code that was added in Apollo Client 2.5.

Stay tuned for more details (and commits) next week!

Comment on lines +523 to +526
it("can define custom merge functions", function () {
const cache = new InMemoryCache({
typePolicies: {
Person: {
Copy link
Member Author

@benjamn benjamn Oct 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In lieu of full documentation, this test case gives a pretty good illustration of how to use typePolicies and field policies to implement pagination.

benjamn added a commit that referenced this pull request Oct 11, 2019
This size will come back down once we remove the existing implementations
of functionality replaced by PR #5443.
benjamn added a commit that referenced this pull request Oct 15, 2019
This size will come back down once we remove the existing implementations
of functionality replaced by PR #5443.
@benjamn benjamn force-pushed the cache-policies branch 2 times, most recently from 39948f8 to 88c8ed9 Compare October 15, 2019 16:56
benjamn added a commit that referenced this pull request Oct 15, 2019
This size will come back down once we remove the existing implementations
of functionality replaced by PR #5443.
benjamn added a commit that referenced this pull request Oct 16, 2019
This size will come back down once we remove the existing implementations
of functionality replaced by PR #5443.
@benjamn benjamn mentioned this pull request Oct 16, 2019
31 tasks
benjamn and others added 15 commits October 21, 2019 12:48
Instead of capturing the store:NormalizedCache object using a closure, we
can pass it in as an additional context argument each time we call
storeObjectMerger.merge, like we already do with mergeOverrides.
Although it was tempting to make the read function feel like a GraphQL
resolver function (parentObject, args, context, info), that signature
would not have been appropriate for the merge function, and having to
remember two totally different signatures for reading and merging did not
seem ideal.

Now, the only difference between the signatures is that the merge function
takes incoming data, to be merged with the existing data (if any):

  read(existing, { args, parentObject, field, variables })
  merge(existing, incoming, { args, parentObject, field, variables })

It would have been nice to use named options for everything, including the
existing and incoming parameters, but it's important for those parameters
to be positional so that the developer can specify their types, without
also having to provide a new type for the entire options object.
This size will come back down once we remove the existing implementations
of functionality replaced by PR #5443.
Previously, defining a merge function for an ancestor field would prevent
the merge functions of any descendant fields from being called.
@hwillson hwillson self-requested a review October 21, 2019 18:01
@benjamn
Copy link
Member Author

benjamn commented Oct 21, 2019

While there's still a lot of related work I'd like to tackle—in particular, allowing read functions to return async results, so that they can fully replace local state resolver functions, and finishing the documentation of read and merge functions—I'm confident enough in the current implementation of this PR to merge it as-is (albeit perhaps somewhat prematurely), and continue the remaining work in separate PRs targeting the release-3.0 branch. I realize I never got around to fully explaining these changes in this PR, but that's what the actual documentation is for.

@benjamn benjamn marked this pull request as ready for review October 21, 2019 18:19
@benjamn benjamn merged commit 2c2babc into release-3.0 Oct 21, 2019
@benjamn benjamn deleted the cache-policies branch October 21, 2019 18:24
@apollographql apollographql locked and limited conversation to collaborators Feb 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants