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

feat: Allow returning IGNORE sentinel from optimisticResponse functions to support bailing-out from the optimistic update #11410

Conversation

sf-twingate
Copy link
Contributor

@sf-twingate sf-twingate commented Dec 4, 2023

Summary

This PR updates the behaviour of the optimisticResponse functional property in mutations to support returning null, which will cause the optimistic update to be skipped / bailed out from.

This is useful to support an optimistic response only when certain variables are provided to the mutation. For example, in my use case, I only wish to perform an optimistic update when a specific variable is not included, as I can't reliably compute the result on the client when it is.

Currently, I can workaround this by writing an additional query without an optimisticResponse property for mutations which use this variable, and then conditionally calling one of the two mutations based on the input variables. However, this results in duplicate code and I feel this small API change would make things simpler and might be useful in other use cases.

Notes

I was going to open this as an issue, but opted to write an implementation to support my request. If there's a better way of implementing this, or if the PR is missing something (new to contributing to the codebase!), just let me know and I'm happy to update it.

@apollo-cla
Copy link

@sf-twingate: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/

Copy link

netlify bot commented Dec 4, 2023

👷 Deploy request for apollo-client-docs pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit ef08c05

Copy link

changeset-bot bot commented Dec 4, 2023

🦋 Changeset detected

Latest commit: ef08c05

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@apollo/client Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@sf-twingate sf-twingate changed the title feat: Allow returning null from optimisticResponse functions to bail-out from the optimistic update feat: Allow returning null from optimisticResponse functions, to support bailing-out from the optimistic update Dec 4, 2023
@sf-twingate sf-twingate force-pushed the feature/sf/allow-bailing-from-optimistic-update branch 2 times, most recently from 7e9af0d to 65764d3 Compare December 4, 2023 23:38
@phryneas phryneas added the 🏓 awaiting-team-response requires input from the apollo team label Dec 5, 2023
@alessbell
Copy link
Member

Hi @sf-twingate 👋 Thanks for this draft PR and starting this discussion! We agree that there should be a way to bail out of an optimisticResponse, but have a couple of thoughts before we proceed with this PR.

Since null has semantic meaning in GraphQL, I'd suggest undefined if we stick with a primitive type. But there's another option: returning a sentinel object, an approach we use elsewhere, e.g. DELETE or INVALIDATE sentinels used when interacting with the cache (docs).

Since the current behavior is to always set the cache value to optimisticResponse's return value (() => void results in undefined as well), it's unlikely but possible that someone could be relying on the existing behavior when returning either undefined or null. Unlikely, but possible. The sentinel object approach would be fully backward-compatible and something we could ship in a future minor.

Would you want to implement that change in this PR and convert it out of a draft? The changes should be fairly minimal, and I'd be happy to help if you hit any blockers. Let me know - if not I'd be happy to move this over the finish line. Thanks!

@alessbell alessbell force-pushed the feature/sf/allow-bailing-from-optimistic-update branch from 65764d3 to 18b03bb Compare December 11, 2023 20:15
@alessbell alessbell changed the base branch from main to release-3.9 December 11, 2023 20:15
@alessbell alessbell added 🧞‍♂️ enhancement and removed 🏓 awaiting-team-response requires input from the apollo team labels Dec 11, 2023
@alessbell alessbell added 🧶 minor-release 🥚 backwards-compatible for PRs that do not introduce any breaking changes auto-cleanup 🤖 labels Dec 11, 2023
@alessbell alessbell marked this pull request as ready for review December 11, 2023 20:44
@alessbell alessbell requested a review from a team as a code owner December 11, 2023 20:44
@alessbell
Copy link
Member

@jerelmiller @phryneas I've gone ahead and moved this out of draft against the release-3.9 branch as discussed. The only change I've made is to use an IGNORE sentinel object instead of null.

A note on docs: I updated the optimisticResponse type but after this is merged I'll add an example for skipping an optimistic update.

Thanks for the contribution, @sf-twingate, this is ready for review 🎉

@alessbell alessbell self-assigned this Dec 11, 2023
@@ -626,6 +633,8 @@ export class QueryManager<TStore> {
invariant.error(error);
}
}, mutation.mutationId);

return true;
Copy link
Member

Choose a reason for hiding this comment

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

Now that I'm looking at this again, I'd vote to move the data === IGNORE check out of markMutationOptimistic to avoid changing the fn signature here to one that returns a boolean. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

I'd be ok with this. I'd prefer that as well 🙂

@alessbell alessbell changed the title feat: Allow returning null from optimisticResponse functions, to support bailing-out from the optimistic update feat: Allow returning IGNORE sentinel from optimisticResponse functions to support bailing-out from the optimistic update Dec 11, 2023
Copy link
Member

@jerelmiller jerelmiller left a comment

Choose a reason for hiding this comment

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

Changes are ok by me! @alessbell once you're happy with this, feel free to merge.

@sf-twingate thanks so much for the contribution!

Comment on lines 29 to 30
// conditionally bail out of optimistic updates
return IGNORE;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// conditionally bail out of optimistic updates
return IGNORE;
// conditionally bail out of optimistic updates
return IGNORE;

Minor nit to ensure these are aligned 🙂

@@ -626,6 +633,8 @@ export class QueryManager<TStore> {
invariant.error(error);
}
}, mutation.mutationId);

return true;
Copy link
Member

Choose a reason for hiding this comment

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

I'd be ok with this. I'd prefer that as well 🙂

@sf-twingate
Copy link
Contributor Author

@alessbell sorry for the late response — had a busy work week and didn't yet have a chance to continue with this PR. Thank you for taking care of updating it!

The changes made LGTM — just let me know if you need anything additional from my end to land this 🎉

@alessbell alessbell force-pushed the feature/sf/allow-bailing-from-optimistic-update branch from 9f8f310 to 3dd910d Compare December 15, 2023 17:24
@alessbell alessbell removed the auto-cleanup 🤖 label Dec 15, 2023
@alessbell alessbell merged commit 07fcf6a into apollographql:release-3.9 Dec 15, 2023
27 of 28 checks passed
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants