---
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/).