0

I'm working through the GraphQL JS tutorial and trying to understand how variables work with the queries.

In the Object Types section I can get this working fine:

My server.js file:

const express = require('express')
const graphqlHTTP = require('express-graphql')
const { buildSchema } = require('graphql')

const app = express()

const schema = buildSchema(`
  type RandomDie {
    numSides: Int!
    rollOnce: Int!
    roll(numRolls: Int!): [Int]
  }

  type Query {
    getDie(numSides: Int): RandomDie
  }
`)

class RandomDie {
  constructor(numSides) {
    this.numSides = numSides;
  }

  rollOnce() {
    return 1 + Math.floor(Math.random() * this.numSides);
  }

  roll({numRolls}) {
    var output = [];
    for (var i = 0; i < numRolls; i++) {
      output.push(this.rollOnce());
    }
    return output;
  }}

const root = {
  getDie: ({numSides}) => {
    return new RandomDie(numSides || 6);
  },
}

module.exports = root

app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}))

app.listen(4000)

console.log('Running a GraphQL API server at localhost:4000/graphql')

My random.json file:

{
  "query": "query RollDice($sides: Int) { getDie(numSides: $sides) { rollOnce roll(numRolls: 3) }}",
  "variables": {
    "sides": 6
  }
}

And if I run this command here:

http http://localhost:4000/graphql < ./random.json

I get this output:

{
  "data": {
    "getDie": {
      "roll": [
        1,
        6,
        2
      ],
      "rollOnce": 5
    }
  }
}

My question is this:

How do I set that 3 for numRolls as a variable in the random.json file?

I tried this:

{
  "query": "query RollDice($sides: Int, $rolls: Int) { getDie(numSides: $sides) { rollOnce roll(numRolls: $rolls) }}",
  "variables": {
    "sides": 6,
    "rolls": 3
  }
}

But got this error:

"message": "Variable \"$rolls\" of type \"Int\" used in position expecting type \"Int!\"."

2
  • 1
    you are missing the exclamation mark behind Int query RollDice($sides: Int!, $rolls: Int!) Commented Jan 19, 2018 at 16:27
  • bingo! you're correct @JohannesMerz ... however, I tested without setting $sides: Int! ... I left it as $sides: Int and it still worked. why is the ! necessary for $rolls but not $sides? Commented Jan 19, 2018 at 16:31

1 Answer 1

1

When defining variables, the variable types have to match the types of the inputs they are replacing exactly. While your $rolls variable and the numRolls input type are both integers, you've defined rolls as a nullable integer (Int), while in your schema you've defined the input as a "Non-Null" integer (Int!)

type RandomDie {
  roll(numRolls: Int!): [Int]
}

type Query {
  getDie(numSides: Int): RandomDie
}

Notice that numSides is just an Int while numRolls is defined as a Int!, which is why the ! is not needed for $sides (in fact making $sides an Int! will also throw an error!)

Non-null is a wrapper that tells GraphQL that the input cannot be null (for input types) or the returned field cannot be null (for data types). The thing to keep in mind is that the non-null wrapper turns the type it wraps into a different type from GraphQL's perspective, so Int !== Int!.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.