diff --git a/.prettierignore b/.prettierignore
index b1192ca9af..1801e9556e 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -7,4 +7,5 @@
/denoDist
/websiteDist
/website/out
+/website/**/*.mdx
.next
diff --git a/website/pages/authentication-and-express-middleware.mdx b/website/pages/authentication-and-express-middleware.mdx
index 7198b97189..c03f444496 100644
--- a/website/pages/authentication-and-express-middleware.mdx
+++ b/website/pages/authentication-and-express-middleware.mdx
@@ -3,22 +3,67 @@ title: Authentication and Express Middleware
sidebarTitle: Authentication & Middleware
---
+import { Tabs } from 'nextra/components';
+
It's simple to use any Express middleware in conjunction with `graphql-http`. In particular, this is a great pattern for handling authentication.
To use middleware with a GraphQL resolver, just use the middleware like you would with a normal Express app. The `request` object is then available as the second argument in any resolver.
For example, let's say we wanted our server to log the IP address of every request, and we also want to write an API that returns the IP address of the caller. We can do the former with middleware, and the latter by accessing the `request` object in a resolver. Here's server code that implements this:
+
+
```js
const express = require('express');
const { createHandler } = require('graphql-http/lib/use/express');
const { buildSchema } = require('graphql');
-const schema = buildSchema(`
- type Query {
- ip: String
- }
-`);
+const schema = buildSchema(`type Query { ip: String }`);
+
+function loggingMiddleware(req, res, next) {
+ console.log('ip:', req.ip);
+ next();
+}
+
+const root = {
+ ip(args, context) {
+ return context.ip;
+ },
+};
+
+const app = express();
+app.use(loggingMiddleware);
+app.all(
+ '/graphql',
+ createHandler({
+ schema: schema,
+ rootValue: root,
+ context: (req) => ({
+ ip: req.raw.ip,
+ }),
+ }),
+);
+app.listen(4000);
+console.log('Running a GraphQL API server at localhost:4000/graphql');
+
+````
+
+
+```js
+const express = require('express');
+const { createHandler } = require('graphql-http/lib/use/express');
+const {
+ GraphQLObjectType,
+ GraphQLSchema,
+ GraphQLString,
+} = require('graphql');
+
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: { ip: { type: GraphQLString } },
+ }),
+});
function loggingMiddleware(req, res, next) {
console.log('ip:', req.ip);
@@ -45,7 +90,10 @@ app.all(
);
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
-```
+````
+
+
+
In a REST API, authentication is often handled with a header, that contains an auth token which proves what user is making this request. Express middleware processes these headers and puts authentication data on the Express `request` object. Some middleware modules that handle authentication like this are [Passport](http://passportjs.org/), [express-jwt](https://github.com/auth0/express-jwt), and [express-session](https://github.com/expressjs/session). Each of these modules works with `graphql-http`.
diff --git a/website/pages/basic-types.mdx b/website/pages/basic-types.mdx
index bb69bc145c..b6480a979d 100644
--- a/website/pages/basic-types.mdx
+++ b/website/pages/basic-types.mdx
@@ -2,6 +2,8 @@
title: Basic Types
---
+import { Tabs } from 'nextra/components';
+
In most situations, all you need to do is to specify the types for your API using the GraphQL schema language, taken as an argument to the `buildSchema` function.
The GraphQL schema language supports the scalar types of `String`, `Int`, `Float`, `Boolean`, and `ID`, so you can use these directly in the schema you pass to `buildSchema`.
@@ -12,6 +14,8 @@ To use a list type, surround the type in square brackets, so `[Int]` is a list o
Each of these types maps straightforwardly to JavaScript, so you can just return plain old JavaScript objects in APIs that return these types. Here's an example that shows how to use some of these basic types:
+
+
```js
const express = require('express');
const { createHandler } = require('graphql-http/lib/use/express');
@@ -26,6 +30,56 @@ const schema = buildSchema(`
}
`);
+// The root provides a resolver function for each API endpoint
+const root = {
+ quoteOfTheDay() {
+ return Math.random() < 0.5 ? 'Take it easy' : 'Salvation lies within';
+ },
+ random() {
+ return Math.random();
+ },
+ rollThreeDice() {
+ return [1, 2, 3].map((\_) => 1 + Math.floor(Math.random() \* 6));
+ },
+};
+
+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');
+
+````
+
+
+```js
+const express = require('express');
+const { createHandler } = require('graphql-http/lib/use/express');
+const {
+ GraphQLObjectType,
+ GraphQLSchema,
+ GraphQLString,
+ GraphQLFloat,
+ GraphQLList,
+} = require('graphql');
+
+// Construct a schema
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ quoteOfTheDay: { type: GraphQLString },
+ random: { type: GraphQLFloat },
+ rollThreeDice: { type: new GraphQLList(GraphQLFloat) },
+ },
+ }),
+});
+
// The root provides a resolver function for each API endpoint
const root = {
quoteOfTheDay() {
@@ -40,6 +94,7 @@ const root = {
};
const app = express();
+
app.all(
'/graphql',
createHandler({
@@ -47,9 +102,13 @@ app.all(
rootValue: root,
}),
);
+
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
-```
+````
+
+
+
If you run this code with `node server.js` and browse to http://localhost:4000/graphql you can try out these APIs.
diff --git a/website/pages/constructing-types.mdx b/website/pages/constructing-types.mdx
index 33b9c2fe0e..2ae7b93872 100644
--- a/website/pages/constructing-types.mdx
+++ b/website/pages/constructing-types.mdx
@@ -2,26 +2,30 @@
title: Constructing Types
---
+import { Tabs } from 'nextra/components';
+
For many apps, you can define a fixed schema when the application starts, and define it using GraphQL schema language. In some cases, it's useful to construct a schema programmatically. You can do this using the `GraphQLSchema` constructor.
When you are using the `GraphQLSchema` constructor to create a schema, instead of defining `Query` and `Mutation` types solely using schema language, you create them as separate object types.
For example, let's say we are building a simple API that lets you fetch user data for a few hardcoded users based on an id. Using `buildSchema` we could write a server with:
+
+
```js
const express = require('express');
const { createHandler } = require('graphql-http/lib/use/express');
const { buildSchema } = require('graphql');
const schema = buildSchema(`
- type User {
- id: String
- name: String
- }
-
- type Query {
- user(id: String): User
- }
+type User {
+ id: String
+ name: String
+}
+
+type Query {
+ user(id: String): User
+}
`);
// Maps id to User object
@@ -52,10 +56,10 @@ app.all(
);
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
-```
-
-We can implement this same API without using GraphQL schema language:
+````
+
+
```js
const express = require('express');
const { createHandler } = require('graphql-http/lib/use/express');
@@ -110,8 +114,11 @@ app.all(
);
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
-```
+````
+
+
+
-When we use this method of creating the API, the root level resolvers are implemented on the `Query` and `Mutation` types rather than on a `root` object.
+When we use the `GraphQLSchema` constructor method of creating the API, the root level resolvers are implemented on the `Query` and `Mutation` types rather than on a `root` object.
-This is particularly useful if you want to create a GraphQL schema automatically from something else, like a database schema. You might have a common format for something like creating and updating database records. This is also useful for implementing features like union types which don't map cleanly to ES6 classes and schema language.
+This can be particularly useful if you want to create a GraphQL schema automatically from something else, like a database schema. You might have a common format for something like creating and updating database records. This is also useful for implementing features like union types which don't map cleanly to ES6 classes and schema language.
diff --git a/website/pages/getting-started.mdx b/website/pages/getting-started.mdx
index 5721ce762c..049f35ef13 100644
--- a/website/pages/getting-started.mdx
+++ b/website/pages/getting-started.mdx
@@ -3,6 +3,8 @@ title: Getting Started With GraphQL.js
sidebarTitle: Getting Started
---
+import { Tabs } from 'nextra/components';
+
{/* title can be removed in Nextra 4, since sidebar title will take from first h1 */}
# Getting Started With GraphQL.js
@@ -19,7 +21,7 @@ and arrow functions, so if you aren't familiar with them you might want to read
To create a new project and install GraphQL.js in your current directory:
-```bash
+```sh npm2yarn
npm init
npm install graphql --save
```
@@ -28,18 +30,49 @@ npm install graphql --save
To handle GraphQL queries, we need a schema that defines the `Query` type, and we need an API root with a function called a “resolver” for each API endpoint. For an API that just returns “Hello world!”, we can put this code in a file named `server.js`:
+
+
```javascript
-let { graphql, buildSchema } = require('graphql');
+const { graphql, buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
-let schema = buildSchema(`
- type Query {
- hello: String
- }
-`);
+const schema = buildSchema(`type Query { hello: String } `);
+
+// The rootValue provides a resolver function for each API endpoint
+const rootValue = {
+ hello() {
+ return 'Hello world!';
+ },
+};
+
+// Run the GraphQL query '{ hello }' and print out the response
+graphql({
+ schema,
+ source: '{ hello }',
+ rootValue,
+ }).then((response) => {
+ console.log(response);
+ });
+});
+
+````
+
+
+```javascript
+const { graphql, GraphQLSchema, GraphQLObjectType } = require('graphql');
+
+// Construct a schema
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ hello: { type: GraphQLString },
+ },
+ }),
+});
// The rootValue provides a resolver function for each API endpoint
-let rootValue = {
+const rootValue = {
hello() {
return 'Hello world!';
},
@@ -53,7 +86,10 @@ graphql({
}).then((response) => {
console.log(response);
});
-```
+````
+
+
+
If you run this with:
diff --git a/website/pages/mutations-and-input-types.mdx b/website/pages/mutations-and-input-types.mdx
index 91f101107e..7b4bfa4859 100644
--- a/website/pages/mutations-and-input-types.mdx
+++ b/website/pages/mutations-and-input-types.mdx
@@ -2,10 +2,14 @@
title: Mutations and Input Types
---
+import { Tabs } from 'nextra/components';
+
If you have an API endpoint that alters data, like inserting data into a database or altering data already in a database, you should make this endpoint a `Mutation` rather than a `Query`. This is as simple as making the API endpoint part of the top-level `Mutation` type instead of the top-level `Query` type.
Let's say we have a “message of the day” server, where anyone can update the message of the day, and anyone can read the current one. The GraphQL schema for this is simply:
+
+
```graphql
type Mutation {
setMessage(message: String): String
@@ -14,7 +18,34 @@ type Mutation {
type Query {
getMessage: String
}
-```
+````
+
+
+```js
+const {
+ GraphQLObjectType,
+ GraphQLString,
+ GraphQLSchema,
+} = require('graphql');
+
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ getMessage: { type: GraphQLString },
+ },
+ }),
+ mutation: new GraphQLObjectType({
+ name: 'Mutation',
+ fields: {
+ setMessage: { type: GraphQLString },
+ },
+ }),
+});
+````
+
+
+
It's often convenient to have a mutation that maps to a database create or update operation, like `setMessage`, return the same thing that the server stored. That way, if you modify the data on the server, the client can learn about those modifications.
@@ -37,6 +68,8 @@ You don't need anything more than this to implement mutations. But in many cases
For example, instead of a single message of the day, let's say we have many messages, indexed in a database by the `id` field, and each message has both a `content` string and an `author` string. We want a mutation API both for creating a new message and for updating an old message. We could use the schema:
+
+
```graphql
input MessageInput {
content: String
@@ -57,7 +90,72 @@ type Mutation {
createMessage(input: MessageInput): Message
updateMessage(id: ID!, input: MessageInput): Message
}
-```
+
+````
+
+
+```js
+const {
+ GraphQLObjectType,
+ GraphQLString,
+ GraphQLSchema,
+ GraphQLID,
+ GraphQLInputObjectType,
+ GraphQLNonNull,
+} = require('graphql');
+
+const MessageInput = new GraphQLInputObjectType({
+ name: 'MessageInput',
+ fields: {
+ content: { type: GraphQLString },
+ author: { type: GraphQLString },
+ },
+});
+
+const Message = new GraphQLObjectType({
+ name: 'Message',
+ fields: {
+ id: { type: GraphQLID },
+ content: { type: GraphQLString },
+ author: { type: GraphQLString },
+ },
+});
+
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ getMessage: {
+ type: Message,
+ args: {
+ id: { type: new GraphQLNonNull(GraphQLID) },
+ },
+ },
+ },
+ }),
+ mutation: new GraphQLObjectType({
+ name: 'Mutation',
+ fields: {
+ createMessage: {
+ type: Message,
+ args: {
+ input: { type: new GraphQLNonNull(MessageInput) },
+ },
+ },
+ updateMessage: {
+ type: Message,
+ args: {
+ id: { type: new GraphQLNonNull(GraphQLID) },
+ input: { type: new GraphQLNonNull(MessageInput) },
+ },
+ },
+ },
+ }),
+});
+````
+
+
+
Here, the mutations return a `Message` type, so that the client can get more information about the newly-modified `Message` in the same request as the request that mutates it.
@@ -67,32 +165,34 @@ Naming input types with `Input` on the end is a useful convention, because you w
Here's some runnable code that implements this schema, keeping the data in memory:
+
+
```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 */ `
- input MessageInput {
- content: String
- author: String
- }
+const schema = buildSchema(`
+input MessageInput {
+ content: String
+ author: String
+}
- type Message {
- id: ID!
- content: String
- author: String
- }
+type Message {
+ id: ID!
+ content: String
+ author: String
+}
- type Query {
- getMessage(id: ID!): Message
- }
+type Query {
+ getMessage(id: ID!): Message
+}
- type Mutation {
- createMessage(input: MessageInput): Message
- updateMessage(id: ID!, input: MessageInput): Message
- }
+type Mutation {
+ createMessage(input: MessageInput): Message
+ updateMessage(id: ID!, input: MessageInput): Message
+}
`);
// If Message had any complex fields, we'd put them on this object.
@@ -131,6 +231,118 @@ const root = {
},
};
+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');
+});
+
+````
+
+
+```js
+const express = require('express');
+const { createHandler } = require('graphql-http/lib/use/express');
+const {
+ GraphQLObjectType,
+ GraphQLString,
+ GraphQLSchema,
+ GraphQLID,
+ GraphQLInputObjectType,
+ GraphQLNonNull,
+} = require('graphql');
+
+const MessageInput = new GraphQLInputObjectType({
+ name: 'MessageInput',
+ fields: {
+ content: { type: GraphQLString },
+ author: { type: GraphQLString },
+ },
+});
+
+const Message = new GraphQLObjectType({
+ name: 'Message',
+ fields: {
+ id: { type: GraphQLID },
+ content: { type: GraphQLString },
+ author: { type: GraphQLString },
+ },
+});
+
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ getMessage: {
+ type: Message,
+ args: {
+ id: { type: new GraphQLNonNull(GraphQLID) },
+ },
+ },
+ },
+ }),
+ mutation: new GraphQLObjectType({
+ name: 'Mutation',
+ fields: {
+ createMessage: {
+ type: Message,
+ args: {
+ input: { type: new GraphQLNonNull(MessageInput) },
+ },
+ },
+ updateMessage: {
+ type: Message,
+ args: {
+ id: { type: new GraphQLNonNull(GraphQLID) },
+ input: { type: new GraphQLNonNull(MessageInput) },
+ },
+ },
+ },
+ }),
+});
+
+// If Message had any complex fields, we'd put them on this object.
+class Message {
+ constructor(id, { content, author }) {
+ this.id = id;
+ this.content = content;
+ this.author = author;
+ }
+}
+
+// Maps username to content
+const fakeDatabase = {};
+
+const root = {
+ getMessage({ id }) {
+ if (!fakeDatabase[id]) {
+ throw new Error('no message exists with id ' + id);
+ }
+ return new Message(id, fakeDatabase[id]);
+ },
+ createMessage({ input }) {
+ // Create a random id for our "database".
+ const id = require('crypto').randomBytes(10).toString('hex');
+
+ fakeDatabase[id] = input;
+ return new Message(id, input);
+ },
+ updateMessage({ id, input }) {
+ if (!fakeDatabase[id]) {
+ throw new Error('no message exists with id ' + id);
+ }
+ // This replaces all old data, but some apps might want partial update.
+ fakeDatabase[id] = input;
+ return new Message(id, input);
+ },
+};
+
const app = express();
app.all(
'/graphql',
@@ -142,7 +354,10 @@ app.all(
app.listen(4000, () => {
console.log('Running a GraphQL API server at localhost:4000/graphql');
});
-```
+````
+
+
+
To call a mutation, you must use the keyword `mutation` before your GraphQL query. To pass an input type, provide the data written as if it's a JSON object. For example, with the server defined above, you can create a new message and return the `id` of the new message with this operation:
diff --git a/website/pages/object-types.mdx b/website/pages/object-types.mdx
index 6699e049fc..366620c970 100644
--- a/website/pages/object-types.mdx
+++ b/website/pages/object-types.mdx
@@ -2,18 +2,56 @@
title: Object Types
---
+import { Tabs } from 'nextra/components';
+
In many cases, you don't want to return a number or a string from an API. You want to return an object that has its own complex behavior. GraphQL is a perfect fit for this.
In GraphQL schema language, the way you define a new object type is the same way we have been defining the `Query` type in our examples. Each object can have fields that return a particular type, and methods that take arguments. For example, in the [Passing Arguments](/passing-arguments/) documentation, we had a method to roll some random dice:
+
+
```graphql
type Query {
rollDice(numDice: Int!, numSides: Int): [Int]
}
```
+
+
+```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)
+ },
+ },
+ },
+ },
+})
+
+````
+
+
If we wanted to have more and more methods based on a random die over time, we could implement this with a `RandomDie` object type instead.
+
+
```graphql
type RandomDie {
roll(numRolls: Int!): [Int]
@@ -22,7 +60,53 @@ type RandomDie {
type Query {
getDie(numSides: Int): RandomDie
}
-```
+````
+
+
+
+```js
+const {
+ GraphQLObjectType,
+ GraphQLNonNull,
+ GraphQLInt,
+ GraphQLString,
+ GraphQLList,
+ GraphQLFloat,
+} = require('graphql');
+
+const RandomDie = new GraphQLObjectType({
+ name: 'RandomDie',
+ fields: {
+ roll: {
+ type: new GraphQLList(GraphQLInt),
+ args: {
+ numRolls: {
+ type: new GraphQLNonNull(GraphQLInt)
+ }
+ }
+ }
+ }
+});
+
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ getDie: {
+ type: RandomDie,
+ args: {
+ numSides: {
+ type: GraphQLInt
+ }
+ }
+ }
+ }
+ })
+});
+
+````
+
+
Instead of a root-level resolver for the `RandomDie` type, we can instead use an ES6 class, where the resolvers are instance methods. This code shows how the `RandomDie` schema above can be implemented:
@@ -50,10 +134,12 @@ const root = {
return new RandomDie(numSides || 6);
},
};
-```
+````
For fields that don't use any arguments, you can use either properties on the object or instance methods. So for the example code above, both `numSides` and `rollOnce` can actually be used to implement GraphQL fields, so that code also implements the schema of:
+
+
```graphql
type RandomDie {
numSides: Int!
@@ -62,29 +148,170 @@ type RandomDie {
}
type Query {
- getDie(numSides: Int): RandomDie
+getDie(numSides: Int): RandomDie
}
-```
+
+````
+
+
+```js
+const {
+ GraphQLObjectType,
+ GraphQLNonNull,
+ GraphQLInt,
+ GraphQLString,
+ GraphQLList,
+ GraphQLFloat,
+} = require('graphql');
+
+const RandomDie = new GraphQLObjectType({
+ name: 'RandomDie',
+ fields: {
+ numSides: {
+ type: new GraphQLNonNull(GraphQLInt),
+ },
+ rollOnce: {
+ type: new GraphQLNonNull(GraphQLInt),
+ },
+ roll: {
+ type: new GraphQLList(GraphQLInt),
+ args: {
+ numRolls: {
+ type: new GraphQLNonNull(GraphQLInt)
+ },
+ }
+ }
+ }
+});
+
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ getDie: {
+ type: RandomDie,
+ args: {
+ numSides: {
+ type: GraphQLInt
+ }
+ }
+ }
+ }
+ })
+});
+````
+
+
+
Putting this all together, here is some sample code that runs a server with this GraphQL API:
+
+
```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 RandomDie {
- numSides: Int!
- rollOnce: Int!
- roll(numRolls: Int!): [Int]
+const schema = buildSchema(`
+type RandomDie {
+ numSides: Int!
+ rollOnce: Int!
+ roll(numRolls: Int!): [Int]
+}
+
+type Query {
+ getDie(numSides: Int): RandomDie
+}
+`);
+
+// This class implements the RandomDie GraphQL type
+class RandomDie {
+ constructor(numSides) {
+ this.numSides = numSides;
}
- type Query {
- getDie(numSides: Int): RandomDie
+ rollOnce() {
+ return 1 + Math.floor(Math.random() \* this.numSides);
}
-`);
+
+ roll({ numRolls }) {
+ const output = [];
+ for (const i = 0; i < numRolls; i++) {
+ output.push(this.rollOnce());
+ }
+ return output;
+ }
+}
+
+// The root provides the top-level API endpoints
+const root = {
+ getDie({ numSides }) {
+ return new RandomDie(numSides || 6);
+ },
+};
+
+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');
+````
+
+
+```js
+const express = require('express');
+const { createHandler } = require('graphql-http/lib/use/express');
+const {
+ GraphQLObjectType,
+ GraphQLNonNull,
+ GraphQLInt,
+ GraphQLString,
+ GraphQLList,
+ GraphQLFloat,
+} = require('graphql');
+
+const RandomDie = new GraphQLObjectType({
+ name: 'RandomDie',
+ fields: {
+ numSides: {
+ type: new GraphQLNonNull(GraphQLInt),
+ },
+ rollOnce: {
+ type: new GraphQLNonNull(GraphQLInt),
+ },
+ roll: {
+ type: new GraphQLList(GraphQLInt),
+ args: {
+ numRolls: {
+ type: new GraphQLNonNull(GraphQLInt)
+ },
+ }
+ }
+ }
+});
+
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ getDie: {
+ type: RandomDie,
+ args: {
+ numSides: {
+ type: GraphQLInt
+ }
+ }
+ }
+ }
+ })
+});
// This class implements the RandomDie GraphQL type
class RandomDie {
@@ -122,7 +349,10 @@ app.all(
);
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
-```
+````
+
+
+
When you issue a GraphQL query against an API that returns object types, you can call multiple methods on the object at once by nesting the GraphQL field names. For example, if you wanted to call both `rollOnce` to roll a die once, and `roll` to roll a die three times, you could do it with this query:
diff --git a/website/pages/passing-arguments.mdx b/website/pages/passing-arguments.mdx
index db67d98a0e..0017a69638 100644
--- a/website/pages/passing-arguments.mdx
+++ b/website/pages/passing-arguments.mdx
@@ -2,6 +2,8 @@
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
@@ -12,17 +14,51 @@ type Query {
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:
+
+
```graphql
type Query {
rollDice(numDice: Int!, numSides: Int): [Int]
}
```
+
+
+```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)
+ },
+ },
+ },
+ },
+})
+
+````
+
+
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:
-```javascript
+```js
const root = {
rollDice(args) {
const output = [];
@@ -32,11 +68,11 @@ const root = {
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
-```javascript
+```js
const root = {
rollDice({ numDice, numSides }) {
const output = [];
@@ -52,17 +88,72 @@ If you're familiar with destructuring, this is a bit nicer because the line of c
The entire code for a server that hosts this `rollDice` API is:
+
+
```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]
- }
-`);
+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');
+
+````
+
+
+```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 = {
@@ -85,7 +176,10 @@ app.all(
);
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
-```
+````
+
+
+
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:
diff --git a/website/pages/running-an-express-graphql-server.mdx b/website/pages/running-an-express-graphql-server.mdx
index 2d51c4b52c..dbaff0a087 100644
--- a/website/pages/running-an-express-graphql-server.mdx
+++ b/website/pages/running-an-express-graphql-server.mdx
@@ -3,28 +3,28 @@ title: Running an Express GraphQL Server
sidebarTitle: Running Express + GraphQL
---
+import { Tabs } from 'nextra/components';
+
The simplest way to run a GraphQL API server is to use [Express](https://expressjs.com), a popular web application framework for Node.js. You will need to install two additional dependencies:
-```bash
+```sh npm2yarn
npm install express graphql-http graphql --save
```
Let's modify our “hello world” example so that it's an API server rather than a script that runs a single query. We can use the 'express' module to run a webserver, and instead of executing a query directly with the `graphql` function, we can use the `graphql-http` library to mount a GraphQL API server on the “/graphql” HTTP endpoint:
-```js
-const express = require('express');
-const { createHandler } = require('graphql-http/lib/use/express');
+
+
+```javascript
const { buildSchema } = require('graphql');
+const { createHandler } = require('graphql-http/lib/use/express');
+const express = require('express');
// Construct a schema, using GraphQL schema language
-const schema = buildSchema(`
- type Query {
- hello: String
- }
-`);
-
-// The root provides a resolver function for each API endpoint
-const root = {
+const schema = buildSchema(`type Query { hello: String } `);
+
+// The rootValue provides a resolver function for each API endpoint
+const rootValue = {
hello() {
return 'Hello world!';
},
@@ -44,7 +44,50 @@ app.all(
// Start the server at port
app.listen(4000);
console.log('Running a GraphQL API server at http://localhost:4000/graphql');
-```
+
+````
+
+
+```javascript
+const { GraphQLObjectType, GraphQLSchema } = require('graphql');
+const { createHandler } = require('graphql-http/lib/use/express');
+const express = require('express');
+
+// Construct a schema
+const schema = new GraphQLSchema({
+ query: new GraphQLObjectType({
+ name: 'Query',
+ fields: {
+ hello: { type: GraphQLString },
+ },
+ }),
+});
+
+// The rootValue provides a resolver function for each API endpoint
+const rootValue = {
+ hello() {
+ return 'Hello world!';
+ },
+};
+
+const app = express();
+
+// Create and use the GraphQL handler.
+app.all(
+ '/graphql',
+ createHandler({
+ schema: schema,
+ rootValue: root,
+ }),
+);
+
+// Start the server at port
+app.listen(4000);
+console.log('Running a GraphQL API server at http://localhost:4000/graphql');
+````
+
+
+
You can run this GraphQL server with: