graphql-jit
graphql-jit copied to clipboard
Discrepancy between graphql-js and graphql-jit handling of mutation variables
Consider the following code:
const { graphql, parse } = require('graphql')
const { makeExecutableSchema } = require('@graphql-tools/schema')
const { compileQuery } = require('graphql-jit')
const schema = makeExecutableSchema({
typeDefs: `
input HelloParams { id1: Int id2: Int }
type Mutation { hello(params: HelloParams!): String }
type Query { abc: String }
`,
resolvers: {
Mutation: {
hello: (_parent, args, _context, _info) => {
console.log(JSON.stringify(args, null, 4))
return 'world'
},
},
Query: {
abc: () => 'def'
}
}
})
const source = `mutation myMutation($id1: Int, $id2: Int) {
hello(params: {id1: $id1, id2: $id2})
}`
const variableValues = {
id1: 12,
}
const compiledQuery = compileQuery(schema, parse(source))
;(async () => {
console.log('Begin JIT')
await compiledQuery.query(undefined, null, variableValues)
console.log('Begin plain')
await graphql({ schema, source, variableValues })
console.log('Done')
})('def')
The parameters passed to the resolver differ as seen from the output:
Begin JIT
{
"params": {
"id1": 12,
"id2": null
}
}
Begin plain
{
"params": {
"id1": 12
}
}
Done
In particular, graphql-jit adds a null-valued property for a parameter whose corresponding variable is missing, whereas graphql-js omits the property for which the variable is missing. Note that if we pass id1
and id2
as optional parameters to the mutation directly, both graphql-js and graphql-jit will only pass id1
to the resolver.
Thus, it looks like, for a required object-valued parameter whose properties are optional, graphql-jit will pass to the resolver an object with all properties set (nulls for absent properties), whereas graphql-js will pass to the resolver an object with properties omitted for those that are missing values among the variables.
Would it be possible to modify graphql-jit to also strip missing properties the same way that graphql-js does?