-
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
Support for @skip
and @include
#275
Conversation
Field, | ||
BooleanValue, | ||
Variable, | ||
} from 'graphql'; |
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.
Does this import all of graphql now, because the exact path isn't specified?
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.
These are just the types, it doesn't actually import anything afaik
Quick question: would it not be possible to apply skip and include directives in a way that's as simple as the way it's done in graphql-js? That way seems pretty straight forward: |
This implementation is pretty similar other than the fact that it allows us to easily incorporate the addition of other directives once/if the GraphQL spec adds them. In the GraphQL AST, there is a |
The thing that confuses me is that I don't know what it means to resolve a directive? Isn't that just applying a directive? Also, I'm slightly skeptical that we can easily support other directives. So far all the directives I've seen will require somehow executing the query differently, and even returning the result differently. Since it's not quite clear what those changes might be, it could make sense to just support skip and include in the simplest way, which is by removing nodes when the directives apply. I'd be happy to be convinced otherwise, for instance with an example of how the current approach would easily let us support deferred and live directives. |
I was imagining that supporting directives that actually modify the selections within a particular query (e.g. something like |
For context other directives we might want to support include defer and poll. |
After discussion with @helfer, I'll go ahead an implement a Other directives, such as |
…rbage when it runs
} = {}): ApolloStore { | ||
const enhancers = []; | ||
|
||
if (reportCrashes === undefined) { |
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.
I had to add this because otherwise one of the unit tests would print all of this useless stuff every time it ran because it irked the crash reporter.
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.
I'm not sure I understand, can you show me later?
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.
Use the TypeScript default argument syntax, reportCrashes = true
…ver as part of a query even if they weren't in the store
@skip
and @include
@@ -120,6 +124,8 @@ export function diffSelectionSetAgainstStore({ | |||
selectionSet.selections.forEach((selection) => { | |||
// Don't push more than one missing field per field in the query | |||
let missingFieldPushed = false; | |||
const included = shouldInclude(selection, variables); |
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.
move this definition down to just before it is used.
and call it something other than included
, maybe includeField
assert.deepEqual(query, queryClone); | ||
}); | ||
|
||
it('throws an error on an unsupported directive', () => { |
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 don't need this, we can just ignore directives we don't know about.
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.
As discussed, leaving this and the change below in the PR but added a note that mentions that we should move it into the validators at some point.
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.
I'm not so sure about this - all directives I've heard about have required the client to know about them to work - skip
, defer
, etc.
This looks good, you can merge it after some minor changes. |
}): FieldDiffResult { | ||
const storeObj = store[rootId] || {}; | ||
const storeFieldKey = storeKeyNameFromField(field, variables); | ||
if (included === undefined) { |
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.
This should be typeof included === 'undefined'
.
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 don't need this check at all if we use typescript default arg syntax
@@ -710,6 +718,88 @@ describe('client', () => { | |||
}); | |||
}); | |||
|
|||
describe('directives', () => { |
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.
I think we can move these tests to roundtrip.ts
, they will be much more concise there. No need to exercise querymanager for all of them, IMO.
Implements support for
@skip
and@include
(see #237).TODO: