-
Notifications
You must be signed in to change notification settings - Fork 153
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
Query/Mutation params: null vs undefined #236
Comments
Out of interest, what should the behaviour be here in your opinion? I ask because When we see a Based on the behaviour here, it sounds like any undefined argument values are essentially being stripped out of the Cypher, essentially leaving: query($id: ID) {
user(where:{ }) {
name
}
} This would behave as you describe, returning all User values in the database... And honestly I'm on the fence as to whether or not this is even the incorrect behaviour. Treating |
I would lean towards under-fetching here, assuming that the act of specifying
In pure semantic terms, I suppose "give me all records where id is null" would return all records with the id property as IS NULL, and "give me all records where id is undefined" would return all records without an In this case though, my initial instinct says the safer solution is to treat |
I agree that the current behaviour is open to mistakes being made - an inconvenience in development, but a potential nightmare in production. I would definitely say two options here:
Curious to see is @danstarns has any thoughts on the above, or any alternative suggestions? As a slight side note, was doing a bit of general research on this and came across this comment: graphql/graphql-js#731 (comment)
This observation definitely fits into the second option above I think. |
Wouldnt it be a lovely world if all languages and runtimes had only one bottom value? Generally, I think null is the appropriate value to be used for filtering and undefined has no effect. We cannot actually do much about undefined as my example below shows: const { makeExecutableSchema } = require("@graphql-tools/schema");
const { graphqlSync } = require("graphql");
const typeDefs = `
input Input {
here: String
notHere: String
}
type Query {
test(input: Input!): String
}
`;
const resolvers = {
Query: {
test(root, { input }) {
console.log(input);
/*
{ here: 'I am here' } <----------------------------------------------------------------- 👀
*/
return "test";
},
},
};
const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
const query = `
query($input: Input!) {
test(input: $input)
}
`;
const variableValues = {
input: {
here: "I am here",
notHere: undefined,
},
};
const response = graphqlSync({ schema, source: query, variableValues });
console.log(response); Notice how the logged input object does not contain the Finally, on the worry about a potential nightmare in production, I will suggest securing your API with the |
That's certainly an interesting observation that arguments with value undefined don't even reach the resolver - I wonder if they're in the ResolveInfo object? Nice example. 🏆 Perhaps there is something we can do with "empty where" arguments, and instead have the absence of that argument meaning "match everything" and throw and error if it's empty? |
That seems sensible at first blush. Is it as simple as "An empty input is an invalid input." Are there any instances where an empty input would be desirable? |
There are... This would be quite an API redesign, and it would change the expectations of a lot of users. It's gonna require a bit of thought, and probably bigger fish to fry in the meantime. |
I just had the issue of accidentally updating hundreds of nodes with the same value after I failed to include a variable with a mutation client side. At first I was annoyed that neither Apollo Client nor Server had caught the missing variable. Subsequent reading suggests this is avoidable by making the argument type required Still, it was interesting and I think this scenario reinforces the value of undefined being treated as missing since GraphQL is seemingly designed around the possibility. Ideally for me this library would expose an override flag for enforcing variable existence when passing a where condition but I'm not sure of this is actually possible. |
In my schema I resorted to writing my mutations manually, and created So a MaybeStringValue is
In my schema builder I just iterate over the scalar types I want to support, and generate required, maybe, and array variants. That way the caller can express the semantic difference between wanting a value set to null, vs not specifying a value to change. |
Behaviour is different when passing
null
orundefined
to a query or mutation.In this example, if
$id
isnull
then no users are returned. if$id
isundefined
then all users are returned.This is especially dangerous when dealing with mutations:
If
$teamID
isnull
, this user will be connected to no teams (as expected). If$team ID
isundefined
this user will be connected to EVERY team! I guess if the database included millions of teams this would be enough to cause serious problems.The text was updated successfully, but these errors were encountered: