Skip to content
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

Discrepancy between graphql-js and graphql-jit handling of mutation variables #230

Open
gabrielschulhof opened this issue Sep 15, 2023 · 1 comment

Comments

@gabrielschulhof
Copy link

gabrielschulhof commented Sep 15, 2023

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?

@trkohler
Copy link
Contributor

Would it be possible to modify graphql-jit to also strip missing properties the same way that graphql-js does?

the way how graphql-js and graphql-jit work are different. graphql-jit compiles query ahead of execution and during compilation time we don't know if variable would be present or not when you actually run the query. without that context, we can't remove variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants