-
Notifications
You must be signed in to change notification settings - Fork 828
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
@include and @skip directives lead to irrelevant errors #1496
Comments
The GraphQL is a strongly-typed language, and the schema serves as a contract between the client and server. In order for the server to fulfill that contract, it needs to know exactly what fields are queryable and what types they return. If a field is not queryable, it should not be included in the schema to begin with, and the server should not return it as an available field. Therefore, from a design perspective, it makes sense for the server to return an error if a non-queryable field is included in a query, regardless of whether it is excluded using the There's several ways to elegantly solve your issue using the tools GraphQL provides, under the premise that you can modify both APIs:
interface CommonBanana {
id: ID!
common fields
}
type Banana {
id: ID!
common fields
}
type BoxableBanana {
id: ID!
common fields
bananaBox: BananaBox
}
Type Query {
banana: [CommonBanana]
} And then query it like this: query bananas {
banana {
id
commonFields
... on BoxableBanana {
banana_box {
id
size
}
}
}
} In any case, I'd strongly recommend exploring solutions such as Apollo Federation (implemented in I hope my suggestions could provide some help, please feel free let me know if you have further questions. Cheers |
Thank you for the quick reply! And thanks a bunch for the clear recommendations. I think this helps me on my way sufficiently. I will definitely look into Apollo Federation, I hadn't heard about that yet. |
I am unsure whether to put this under bugs or feature requests, because I would consider this to be both.
The directives
@include
and@skip
are awesome concepts, but they miss the mark when a certain field is not queryable. That is, if the boolean variable on which the@include
directive is conditioned evaluates to false, then it would be reasonable to say that it is not relevant whether the field is queryable or not, because the field will simply be omitted in the result anyway.Why is this important? Well, consider we have two APIs that are very similar and share a big part of their graphql schema definition. I work with django-graphene combined with relay, so I'll present my example use case with that context.
Suppose both APIs contain design logic for a fruit store. Both stores have a model they call
Banana
. One store also has a model calledBananaBox
, because the store has some kind of shipping system, whereas the other store does not defineBananaBox
because it does not ship bananas in boxes anywhere. The store that hasBananaBox
simply added a ForeignKey fromBanana
toBananaBox
in order to keep track of which box a banana is in.Both APIs define appropriate django-graphene Nodes for each model, and both APIs define a query endpoint for bananas.
Now, if we want to perform a query somewhat like the following:
That query will fail when executed on the store without the
BananaBox
model. However, one elegant way of solving this problem would be to use the following query:And then specifying
fetch_box: true
orfetch_box: false
in the store with and without box respectively.However, this will result in the following error for the store without the BananaBox:
Cannot query field "banana_box" on type "BananaNode".
I believe this error is irrelevant to answering the query, because havingfetch_box: false
clearly indicates to the server that we are not interested in thebanana_box
field.The graphql documentation about directives mentions that the
@include
and@skip
directives determine what fields are included in the result, and I would argue that excluding a field means that composing the result can be completed without knowledge of whether or not the field is queryable at all.If this BananaNode has a lot of queryable attributes, and we are interested in all of them, defining the
bananas
query twice just because the two APIs differ by one field is quite silly and repetitive, especially when working with more than two similar APIs. If this use case seems far-fetched, please understand that it is really relevant to the application I am developing.The text was updated successfully, but these errors were encountered: