Write a GraphQL server

This is a simple example.

If you have question about the different between REST and GraphQL, you can see RESTful APIs vs GraphQL APIs by Example. On the other hand, you can also see Thinking in GraphQL in relay.

Before you build graphQL server, you need to learn more about what is graphQL. You can see GraphQL website.

Getting Started

I use es6 to write code. and babel to build. I also use yarn instead of npm. As a result, you need to have knowledge about es6, babel and yarn.

Build a server

I use express to build server, and it also need express-graphql to build graphQL.

yarn add express express-graphql

Then, write a default express server in ./src/server.js.

'use strict';
import path from 'path';
import express from 'express';
import graphql from 'express-graphql';
const ENV = process.env.NODE_ENV === 'production';
const app = express();
app.listen(process.env.PORT || (ENV ? 80 : 8000));

Write a schema

Before writing schema, you need to install graphql.

yarn add graphql

Then, write a new file in ./src/schema.js.

'use strict';
import {
GraphQLSchema,
GraphQLObjectType,
GraphQLString
} from 'graphql';
const PageDataType = new GraphQLObjectType({
name: 'PageData',
fields: () => ({
text: {
type: GraphQLString
}
})
});
export default new GraphQLSchema({
query: new GraphQLObjectType({
name: 'page',
fields: () => ({
pageData: {
type: PageDataType,
resolve: () => {
return {
text: 'hello'
};
}
}
})
})
});

Here are two types I use:

  • GraphQLObjectType
  • GraphQLString

You can see details in graphql/types.

Every field in schema needs to set type, and you can also write a custom type like PageDataType I write. GraphQLSchema is root of schema, and you need to write queries and mutations in here. In field, if you have a custom type, you need to check resolve return a correct type to your custom type.

For example, I write a string type of text in GraphQLObjectType. So, resolve in pageData need to return {text: ‘some string’}.

Then, you just need to set schema to server in ./src/server.js.

'use strict';
import path from 'path';
import express from 'express';
import graphql from 'express-graphql';
import schema from './schema';
const ENV = process.env.NODE_ENV === 'production';
const app = express();
app.use('/graphql', graphql({
schema,
graphiql: true
}));
app.listen(process.env.PORT || (ENV ? 80 : 8000));

Test schema

If you set graphiql to true, you can see a website in /graphql.

You can see this website.

You can write a query schema in left part. Like this:

query test {
getData {
text
}
}

And you will get:

{
data: {
getData: {
text: "hello"
}
}
}

The simple example is done.


How to get data from database?

You can add data query in resolve, but you are recommended to use Promise to handle this function. resolve also can accept to return Promise.

...
resolve: () => {
return new Promise((resolve, reject) => {
db.get('SELECT text FROM Page', (err, data)=> {
if(err)
reject(err);
else
resolve({text: data});
})
})

}
...

How to give arguments to query?

You need to add args in field and you can get args in resolve arguments.

...
args: {
id: {
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: (root, {id}) => ({text: id})
...

Then, you use this in query.

query test {
getData(id: "0") {
text
}
}

and get it.

{
data: {
getData: {
text: "0"
}
}
}

Can subschema get data from parent?

If you parent schema have return data, you can get this data in resolve. You also need to remember to return a data. Otherwise you will get a null in subschema.

...
resolve: root => {
//root is your parent data.
}
...

Conclusion

I think REST is easier then graphQL at the beginning. graphQL have to many definitions needed to know. REST is like normal function, so you do not need to learn another thing when you want to use it.

However, maintaining graphQL is easier than REST. That is because getting data from graphQL is decided by client, not server. So adding a new data in graphQL is OK. However. this is not good for REST. If you add new data directly, client may get a data not required or some privacy data will be public. You can also write a new api to return new data, but it will let server be larger. Then, you may maintain difficultly.

If you like to use react, graphQL will be good for you. Owing to relay, you can also use schema in react. You can see the conclusion of relay to learn more information.

So, I think the cost of graphQL is higher and it will be lower when server uses the longer. REST is in contrast of graphQL.
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.