Building a basic GraphQL Server with Node

Learn how to set up a basic GraphQL server in Node and compare the various tools for doing so.

Introduction

So, you know how GraphQL works, you understand how to structure a schema, and you can write basic queries and mutations. But, how do you get a basic GraphQL server running on your own?

This is a topic that a lot of people struggle with, and the process can seem fairly opaque. In reality, it is very easy!

In this section, we will walk through setting up our own basic GraphQL server and discuss the various options available to us.

Setting up a GraphQL server

By far the easiest way to set up a GraphQL server is to use Express. This is a battle-tested web framework, and it has a great deal of support and packages available online.

To get started, let’s create a new Express application along with the express-graphql library:

mkdir graphql-server &&

cd graphql-server &&

npm install express express-graphql graphql --save

When this has completed, create a server.js file and add the following:

import express from 'express';
import { graphqlHTTP } from 'express-graphql';
import { buildSchema } from 'graphql';

// 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 = {
  hello: () => {
    return 'Hello world!';
  },
};

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

Let’s go through this section by section:

import express from 'express'
import { graphqlHTTP } from 'express-graphql';
import { buildSchema } from 'graphql;

Here we import the libraries we need. We are using ES6, so make sure that you can run this. An easy way to get started is to use a resource such as Repl.it

Note: If you have issues with the code above then you may need to adopt the workaround as seen in the GraphQL GitHub repo.

If this were in production, then it is best to adopt modern standards and transpile your code via babel.

So, for our imports:

  • Express is obvious and simply allows us to run the framework

  • GraphqlHTTP is a module that allows us to create an express server based on a graphQL schema

  • buildSchema takes a schema written in SDL and returns a GraphQLSchema object

The last option has a few pitfalls, however, which we will examine later in this chapter.

Here, we create a schema with SDL and pass it into our buildSchema function:

// Construct a schema, using GraphQL schema language
const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

Our initial schema is very simple, and we are just returning a string from a query field named hello.

Next, we need to tell GraphQL where to enter our root query field and resolve our hello query. In this case, we simply return ‘Hello world!’:

// The root provides a resolver function for each API endpoint
const root = {
  hello: () => {
    return 'Hello world!';
  },
};

Finally, we initialize Express and tell it to use the GraphQL library and serve it over HTTP.

We also provide our schema that has been transpiled to a GraphQLSchema object with a rootValue that tells our client where our entry point to get to the data is. We also enable graphiql, which is a graphical interface for our server.

We then run our server on port 4000:

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

And that’s it! You now have a functional GraphQL server and can run it with the following command:

node server.js

You could then run the query:

{
   hello
}

and get this response:

{
   data: {
    hello: "Hello world!"
   }
}

buildSchema vs GraphQLSchema

To keep things simple, and to allow you to use SDL, we used buildSchema in the previous example. Be careful though, as there are a few pitfalls in using this function, namely:

  • It will not allow you to write resolvers for individual fields

  • You cannot use Unions or Interfaces due to the fact that you cannot specify resolveType or isTypeOf properties on your types

  • You cannot leverage custom scalars

buildSchema works by passing your resolver through the root type and executing it. But it will not allow you to write a resolver for a field that is not a root type like Mutation or Query.

A common complaint about not using buildSchema is that you do not get to take advantage of SDL, which makes writing a GraphQL Schema much easier. But actually, using something like makeExecutableSchema from graphql-tools, or a more integrated option like Apollo Server that uses this under the hood, is fine.

This gives you the flexibility to write your schema in SDL and also have a separate resolvers object, giving you the best of both worlds.

For example:

const typeDefs = `
  type Query {
    hello: String
  }
`

const resolvers = {
  Query: {
    hello: () => "Oh hey there!",
  },
}

const schema = makeExecutableSchema({ typeDefs, resolvers })

Conclusion

In this lesson, you learned how to create a basic GraphQL server using Node.js, how to create a schema using SDL, and the pros and cons of writing a schema with buildSchema and makeExecutableSchema.

Using the knowledge from this lesson and the previous lessons, you are now capable of putting together a perfectly usable GraphQL API!

Get hands-on with 1200+ tech skills courses.