-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Allow @directive
and $variable
strings in field policy keyArgs: ["arg", "@dir", "$var"]
arrays
#8678
Allow @directive
and $variable
strings in field policy keyArgs: ["arg", "@dir", "$var"]
arrays
#8678
Conversation
function computeKeyObject( | ||
response: Record<string, any>, | ||
function computeKeyFieldsObject( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We used to (ab)use computeKeyObject
for both keyFields: [...]
and keyArgs: [...]
, but this PR pushed me over the edge to separating them into two separate functions: computeKeyFieldsObject
and computeFieldKeyObject
.
// TODO Cache this work somehow, a la aliasMap? | ||
const directiveName = key.slice(1); | ||
// If the directive appears multiple times, only the first | ||
// occurrence's arguments will be used. TODO Allow repetition? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some TODO
s to consider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this @benjamn! Adding some docs to https://www.apollographql.com/docs/react/caching/advanced-topics/ would be super useful (but we can always track this separately if you'd like to get this PR in place sooner than later to cut a new 3.5 beta).
adc3b73
to
0c4c008
Compare
This section (also about `@connection`) still needs updating: https://www.apollographql.com/docs/react/caching/advanced-topics/#the-connection-directive
@StephenBarlow Can you take a look at the changes from 573a8ea and let me know what you want to do with the other section about Note: I will probably merge this PR soon, and welcome feedback/edits in a follow-up PR. |
b488975
to
5362b19
Compare
Oh hey, that's me |
@directive
and $variable
strings in field policy key: ["arg", "@dir", "$var"]
arrays@directive
and $variable
strings in field policy keyArgs: ["arg", "@dir", "$var"]
arrays
This PR provides a much better solution than the three I proposed in #8659 (comment) to the problem of including more than just arguments in the
keyArgs: [...]
array notation in field policies.While nothing is changing in the way existing
keyArgs: [...]
configurations work, this PR will allow you to refer to directives like the@connection
directive, or query variables, in the same array where you usually specify yourkeyArgs
:Information about directives is included by default in the field key if you don't provide a
keyArgs: [...]
configuration, but is lost when switching tokeyArgs: [...]
, which can be surprising. You can alternatively provide akeyArgs(args, context) {...}
function to return any key you like, takingcontext.field.directives
into account, but that's a lot more involved and error-prone.The cache configuration shown above allows queries to use
@connection(key: ...)
to provide additional identifying information for theQuery.feed
field, which is especially useful when more than oneQuery.feed
query is using the same arguments for that field, but you want to keep the query results separate in the cache:Within the cache, you'll now see field keys like the following:
While the
@connection
directive is a common and widely recommended way to solve this problem, I'm proud to say this implementation does not hard-code support for the@connection
directive. You can name the directive anything you want, and it will serve the same purpose!The
"@connection", ["key"]
syntax is a way to select only thekey
argument from the@connection(key: ..., ignored: ...)
directive in the query, which in this case is determined by the$key
variable, which defaults to"main"
. If you leave out the["key"]
part, all arguments passed to the directive will be included. I recommend locking things down to just the arguments you're expecting.The
$var
syntax seems useful when you want the field's storage key to depend on a variable that's not otherwise passed to that field, perhaps because your server expects the variable to be passed as an argument to a different field than the one you're trying to configure.Both
@directive
and$variable
notations are unambiguous with actual arguments (and with each other), because field argument names can only start with an alphabetical letter or an underscore, according to the spec here and here.The same tolerance we introduced for optional
keyArgs
arguments in #7109 applies to directives and variables, too: when there's no@connection
directive on theQuery.feed
field in the query, or no$var
variable provided by the query (true in this case), those details will simply be omitted from the field key, rather than triggering an error. Note:keyFields: [...]
still throws an exception for missing primary keys.One aesthetic problem with this approach is that theUpdate: I reverted this part, sincekeyArgs
configuration may seem misnamed, since it's handling more than just field arguments. In case that bothers you like it bothers me, I introduced a more general fieldkey
configuration that's synonymous in every way withkeyArgs
(except thatkey
takes precedence if both are provided). I think this new name is the "right" name, since the goal ofkeyArgs
/key
is to come up with a uniquely identifying storage key for the field, not necessarily limited to the provided arguments. This insight allows us to avoid introducing new configurations likekeyDirectives
orkeyVariables
to accompanykeyArgs
, as I considered yesterday in #8659 (comment).key
didn't justify itself IMHO: #8659 (comment)Issues potentially resolved by this PR: