Theres no place like home!

Getting Started with GraphQL, Node, and Express

Eric Bishard
November 22nd, 2019 · 2 min read

This is the first of a series of projects to get you familiar with using GraphQL, React and Apollo. In this tutorial I assume the following:

  • You have node and npm installed
  • You are using Visual Studio Code
  • You understand HTML, CSS, and JS
  • You have read up on the basics of GraphQL

The last item is very important, you should not only know where the basic documentation for GraphQL is, but you should have skimmed through the following three pages:

  • Introduction
  • Queries and Mutations
  • Schemas and Types

If you have not skimmed through these pages, you are not prepared to move forward. At the very least I provide these pages in case you are unsure what a particular line of code is doing in this tutorial.

Project Setup and Dependencies

Create a new directory to house our server and initialize an npm project:

1mkdir gql-server && cd gql-server && npm init -y

Install our dependencies and open our project in Visual Studio Code:

1npm i graphql express express-graphql && code .

We should now have Visual Studio Code open and our project is ready for us to start working in!

Create Our Dummy Data

In a new file named blogs.js, add an array of objects that we can use for data in our GraphQL server:

1module.exports = [
2 {
3 id: 1,
4 title: 'Preferred Color Scheme in React',
5 author: 'Eric Bishard',
6 topic: 'React',
7 url: 'https://www.reactstateofmind.com/preferred-color-scheme-in-react'
8 },
9 {
10 id: 2,
11 title: 'A Guide to Learning React Hooks',
12 author: 'Eric Bishard',
13 topic: 'Hooks',
14 url: 'https://www.reactstateofmind.com/a-guide-to-learning-react-hooks'
15 },
16 {
17 id: 3,
18 title: 'React Accessibility Resources',
19 author: 'Eric Bishard',
20 topic: 'React',
21 url: 'https://www.reactstateofmind.com/react-accessibility-resources'
22 },
23 {
24 id: 4,
25 title: 'React Developer Advocate',
26 author: 'Eric Bishard',
27 topic: 'Devrel',
28 url: 'https://www.reactstateofmind.com/react-developer-advocate'
29 },
30 {
31 id: 5,
32 title: 'Redirect with React Router and Hooks',
33 author: 'Eric Bishard',
34 topic: 'Hooks',
35 url: 'https://www.reactstateofmind.com/redirect-with-react-router-and-hooks'
36 },
37 {
38 id: 6,
39 title: 'Writing From a Beginner Developer\'s Perspective',
40 author: 'Eric Bishard',
41 topic: 'Writing',
42 url: 'https://www.reactstateofmind.com/writing-from-a-beginner-developer-s-perspective'
43 },
44]

Create Our Resolvers

Our GraphQL server will have a few specific endpoints for reading and updating our data.

Given the need to keep things basic I have decided on three endpoints only: blog, blogs and updateBlogTopic.

In a new file named resolvers.js, add the following functions as module.exports:

1let blogData = require('./blogs')
2
3module.exports = {
4 getBlog: (args) => {
5 return blogData.find(blog => blog.id === args.id)
6 },
7 getBlogs: (args) => {
8 return args.topic
9 ? blogData.filter(blog => blog.topic === args.topic)
10 : blogData
11 },
12 updateBlogTopic: ({id, topic}) => {
13 blogData.map(blog => {
14 return blog.id === id
15 ? blog.topic = topic
16 : blog
17 })
18 return blogData.find(blog => blog.id === id)
19 }
20}

In this file we have imported the blog data from our blogs.js file.

The first resolver getBlog will allow us to find a specific blog by id.

The second resolver getBlogs allows getting all of the blog data if no argument is passed or we can get blogs by topic if an argument for topic is passed.

The third resolver updateBlogTopic will set the topic for the blog specified to a new string.

This is not bulletproof code, it’s for demo purposes, but it illustrates how we can serve and manage our data using GraphQL.

Creating the server

In order to create a GraphQL server with a minimal amount of code, we use a package called express-graphql that enables us to define our schema, a root type, and specify if we want the GraphiQL IDE to be enabled.

In a file named server.js we will combine the code needed for express and graphql to work together.

1const express = require('express')
2const graphqlHTTP = require('express-graphql')
3const { buildSchema } = require('graphql')
4
5let { getBlog, getBlogs, updateBlogTopic } = require("./resolvers")
6
7const schema = buildSchema(`
8 type Query {
9 blog(id: Int!): Blog
10 blogs(topic: String): [Blog]
11 }
12 type Mutation {
13 updateBlogTopic(id: Int!, topic: String!): Blog
14 }
15 type Blog {
16 id: Int
17 title: String
18 author: String
19 topic: String
20 url: String
21 }
22`)
23
24const root = {
25 blog: getBlog,
26 blogs: getBlogs,
27 updateBlogTopic: updateBlogTopic
28}
29
30const serverPort = 4000
31const serverUrl = '/graphql'
32
33const app = express()
34app.use(serverUrl, graphqlHTTP({
35 schema: schema,
36 rootValue: root,
37 graphiql: true
38}))
39
40app.listen(serverPort, () => {
41 let message = `GraphQL server now running on http://localhost:${serverPort}${serverUrl}`
42 console.log(message)
43})

In this file we do the following:

  • Import our dependencies (express, express-graphql and graphql)
  • Import our resolvers (which in turn uses our blogs data)
  • Define our GraphQL schema, mutations, and types
  • Define our root type (Our GraphQL endpoints)
  • Create our Express server hosting our GraphQL API

With this final file in place, we are ready to run our project.

Run Our Queries in GraphiQL

In the main project directory (targeting our server.js file) run:

1node server

This will start our Express/GraphQL server and we can click on the link in the terminal: http://localhost:4000/graphql

Here we will see our GraphiQL IDE, let’s test out each of our endpoints and it’s capabilities!

For each example, we will paste the first code sample into the query pane and if a second code sample exists, it will go into the varaibles pane:

Get a Single Blog

1query getSingleBlog($blogID: Int!) {
2 blog(id: $blogID) {
3 title
4 author
5 topic
6 url
7 }
8}
1{"blogID": 1}

Get Blogs by Topic

1query getBlogsByTopic($blogTopic: String!) {
2 blogs(topic: $blogTopic) {
3 title
4 author
5 topic
6 url
7 }
8}
1{"blogTopic": "React"}

Get All Blogs

1query {
2 blogs {
3 title
4 author
5 topic
6 url
7 }
8}

Get Several Blogs by ID Using Fragments

1query getBlogsWithFragment($blogID1: Int!, $blogID2: Int!) {
2 blog1: blog(id: $blogID1) {
3 ...blogFields
4 }
5 blog2: blog(id: $blogID2) {
6 ...blogFields
7 }
8}
9
10fragment blogFields on Blog {
11 title
12 author
13 topic
14 url
15}
1{
2 "blogID1": 1,
3 "blogID2": 2
4}

Mutate/Update Blog Topic by BlogID

1mutation updateBlogTopic($id: Int!, $topic: String!) {
2 updateBlogTopic(id: $id, topic: $topic) {
3 ...blogFields
4 }
5}
6
7fragment blogFields on Blog {
8 title
9 author
10 topic
11 url
12}
1{
2 "id": 2,
3 "topic": "React Hooks"
4}

Summary

We have walked through creating a basic GraphQL server with Node’s Express framework that can handle basic queries and mutations using in-memory data, a list of blogs and learned how to setup resolvers for each endpoint and how to use the GraphiQL IDE to query and test our endpoints and data.

Download the source code on GitHub

More articles from Eric S Bishard

A Guide to Learning React Hooks

This guide provides background on React, state management, and serve as an exhaustive guide to the built in react hooks.

September 20th, 2019 · 2 min read

Jumping into React or Hooks

You should start learning React focusing on fundamentals and using classes...

August 1st, 2019 · 3 min read
Made with 💧 😅 & 😂's in the East Bay
Link to $https://twitter.com/httpjunkieLink to $https://github.com/httpjunkieLink to $https://www.linkedin.com/in/eric-b/Link to $https://stackoverflow.com/users/2623804/eric-bishardLink to $https://medium.com/@httpjunkie