---
title: Passing Arguments
---

import { Tabs } from 'nextra/components';

Just like a REST API, it's common to pass arguments to an endpoint in a GraphQL API. By defining the arguments in the schema language, typechecking happens automatically. Each argument must be named and have a type. For example, in the [Basic Types documentation](/basic-types/) we had an endpoint called `rollThreeDice`:

```graphql
type Query {
  rollThreeDice: [Int]
}
```

Instead of hard coding “three”, we might want a more general function that rolls `numDice` dice, each of which have `numSides` sides. We can add arguments to the GraphQL schema language like this:

<Tabs items={['SDL', 'Code']}>
  <Tabs.Tab>
```graphql
type Query {
  rollDice(numDice: Int!, numSides: Int): [Int]
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```js
const {
  GraphQLObjectType,
  GraphQLNonNull,
  GraphQLInt,
  GraphQLString,
  GraphQLList,
  GraphQLFloat,
} = require('graphql');

new GraphQLObjectType({
  name: 'Query',
  fields: {
    rollDice: {
      type: new GraphQLList(GraphQLFloat),
      args: {
        numDice: {
          type: new GraphQLNonNull(GraphQLInt)
        },
        numSides: {
          type: new GraphQLNonNull(GraphQLInt)
        },
      },
    },
  },
})

````
  </Tabs.Tab>
</Tabs>

The exclamation point in `Int!` indicates that `numDice` can't be null, which means we can skip a bit of validation logic to make our server code simpler. We can let `numSides` be null and assume that by default a die has 6 sides.

So far, our resolver functions took no arguments. When a resolver takes arguments, they are passed as one “args” object, as the first argument to the function. So rollDice could be implemented as:

```js
const root = {
  rollDice(args) {
    const output = [];
    for (const i = 0; i < args.numDice; i++) {
      output.push(1 + Math.floor(Math.random() * (args.numSides || 6)));
    }
    return output;
  },
};
````

It's convenient to use [ES6 destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) for these parameters, since you know what format they will be. So we can also write `rollDice` as

```js
const root = {
  rollDice({ numDice, numSides }) {
    const output = [];
    for (const i = 0; i < numDice; i++) {
      output.push(1 + Math.floor(Math.random() * (numSides || 6)));
    }
    return output;
  },
};
```

If you're familiar with destructuring, this is a bit nicer because the line of code where `rollDice` is defined tells you about what the arguments are.

The entire code for a server that hosts this `rollDice` API is:

<Tabs items={['SDL', 'Code']}>
  <Tabs.Tab>
```js
const express = require('express');
const { createHandler } = require('graphql-http/lib/use/express');
const { buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
const schema = buildSchema(/_ GraphQL _/ ` type Query { rollDice(numDice: Int!, numSides: Int): [Int] }`);

// The root provides a resolver function for each API endpoint
const root = {
  rollDice({ numDice, numSides }) {
    const output = [];
    for (const i = 0; i < numDice; i++) {
      output.push(1 + Math.floor(Math.random() \* (numSides || 6)));
    }
    return output;
  },
};

const app = express();
app.all(
  '/graphql',
  createHandler({
    schema: schema,
    rootValue: root,
  }),
);
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');

````
  </Tabs.Tab>
  <Tabs.Tab>
```js
const express = require('express');
const { createHandler } = require('graphql-http/lib/use/express');
const {
  GraphQLObjectType,
  GraphQLNonNull,
  GraphQLInt,
  GraphQLString,
  GraphQLList,
  GraphQLFloat,
} = require('graphql');

// Construct a schema, using GraphQL schema language
const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'Query',
    fields: {
      rollDice: {
        type: new GraphQLList(GraphQLFloat),
        args: {
          numDice: {
            type: new GraphQLNonNull(GraphQLInt)
          },
          numSides: {
            type: new GraphQLNonNull(GraphQLInt)
          },
        },
      },
    },
  })
})

// The root provides a resolver function for each API endpoint
const root = {
  rollDice({ numDice, numSides }) {
    const output = [];
    for (const i = 0; i < numDice; i++) {
      output.push(1 + Math.floor(Math.random() * (numSides || 6)));
    }
    return output;
  },
};

const app = express();
app.all(
  '/graphql',
  createHandler({
    schema: schema,
    rootValue: root,
  }),
);
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
````

  </Tabs.Tab>
</Tabs>

When you call this API, you have to pass each argument by name. So for the server above, you could issue this GraphQL query to roll three six-sided dice:

```graphql
{
  rollDice(numDice: 3, numSides: 6)
}
```

If you run this code with `node server.js` and browse to http://localhost:4000/graphql you can try out this API.

When you're passing arguments in code, it's generally better to avoid constructing the whole query string yourself. Instead, you can use `$` syntax to define variables in your query, and pass the variables as a separate map.

For example, some JavaScript code that calls our server above is:

```js
const dice = 3;
const sides = 6;
const query = /* GraphQL */ `
  query RollDice($dice: Int!, $sides: Int) {
    rollDice(numDice: $dice, numSides: $sides)
  }
`;

fetch('/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  body: JSON.stringify({
    query,
    variables: { dice, sides },
  }),
})
  .then((r) => r.json())
  .then((data) => console.log('data returned:', data));
```

Using `$dice` and `$sides` as variables in GraphQL means we don't have to worry about escaping on the client side.

With basic types and argument passing, you can implement anything you can implement in a REST API. But GraphQL supports even more powerful queries. You can replace multiple API calls with a single API call if you learn how to [define your own object types](/object-types/).