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.
We'll cover the following
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 aGraphQLSchema
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
orInterfaces
due to the fact that you cannot specifyresolveType
orisTypeOf
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 1400+ tech skills courses.