How to create a GraphQL server with ExpressJS and Apollo Server
Tags: graphql, express, apolloserver, prettier
Published: 2021-01-31 21:15:57

---
title: How to create a GraphQL server with ExpressJS and Apollo Server
published: true
tags: graphql, express, apolloserver, prettier
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ftmeummppq3yps9j479p.jpg
---

In this article, I'm going to show how to create a GraphQL Server using ExpressJS and Apollo Server.

## Crete the project folder and install Apollo Server and Express

```
mkdir graphql-server-playground
cd graphql-server-playground
npm init -y
```

The `package.json` file should be something like this

```
{
  "name": "graphql-server-playground",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

Add description, keywords and author if you want.

In order to setup Express and Apollo Server, install the following dev dependencies

- [@babel/cli](https://www.npmjs.com/package/@babel/cli)
- [@babel/core](https://www.npmjs.com/package/@babel/core)
- [@babel/node](https://www.npmjs.com/package/@babel/node)
- [@babel/preset-env](https://www.npmjs.com/package/@babel/preset-env)
- [nodemon](https://www.npmjs.com/package/nodemon)

```
npm install --save-dev @babel/cli @babel/core @babel/node @babel/preset-env nodemon
```

and the following dependencies

- [apollo-server-express](https://www.npmjs.com/package/apollo-server-express)
- [express](https://www.npmjs.com/package/express)
- [graphql](https://www.npmjs.com/package/graphql)
- graphql-import
- [graphql-tools](https://www.npmjs.com/package/graphql-tools)

```
npm install apollo-server-express express graphql graphql-import graphql-tools
```

Now, in the root folder of your project, create the `src` folder and the `index.js` file in it

```
import express from 'express';
import { ApolloServer, gql } from 'apollo-server-express';

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

const resolvers = {
  Query: {
    hello: () => 'Hello world!',
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

const app = express();
server.applyMiddleware({ app });

app.listen({ port: 4001 }, () =>
  console.log(`🚀 Server ready at http://localhost:4001${server.graphqlPath}`)
);
```

Update the `package.json` file

```
{
  ...
  "main": "src/index.js",
  "scripts": {
    "start": "nodemon --exec babel-node -- ./src/index.js"
  },
  ...
}
```

> `Nodemon` is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.

Before running the server, we have to create a `.babelrc` file in the root folder of the project

```
{
  "presets": ["@babel/preset-env"]
}
```

This file tells NodeJS we are using Babel 7 and that the code has to be transpiled for the browser.

Now start the server with `npm start`

```
npm start

> graphql-server-playground@1.0.0 start graphql-server-playground
> nodemon --exec babel-node -- ./src/index.js

[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `babel-node ./src/index.js`
🚀 Server ready at http://localhost:4001/graphql
```

The GraphQL server is now running on your machine at http://localhost:4001/graphql

## The Playground

The Playground is where you can run your queries and check for the documentation or your schema.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v4oel3e6ktdqjhqcddtk.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jngyudduytchldjgn568.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/a6kevl7s8rsizrcny6t3.png)

The only query available now is the following

```
query {
  hello
}
```

as you can see in the code, it corresponds to this

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

Each query has to have a `resolver`. The resolver is a function that defines what the query returns

```
const resolvers = {
  Query: {
    hello: () => 'Hello world!',
  },
};
```

In this case, the resolver for the `hello` query returns a string, `Hello world!`

If you want to learn more about GraphQL queries and resolvers, take a look [here](https://www.apollographql.com/docs/tutorial/resolvers/).

## Defining the schema

Before defining the schema, we have to decide what kind of data this server will provide to the client.

Let's say we want to store and serve information about our address book. So the data I exptect to have is a list of people whith names, phone numbers and email addresses. Since we don't have a real database for now, let's mock it in the `index.js` file

```
...
const persons = [
	{
		id: 1,
		name: "Ash Ketchum",
		phone_number: "+440000000000",
		email: "ash@gmail.com",
	},
	{
		id: 2,
		name: "Professor Oak",
		phone_number: "+441111111111",
		email: "proak@gmail.com",
	},
	{
		id: 3,
		name: "Gary Oak",
		phone_number: "+442222222222",
	},
];
...
```

This will be our temporary database.

Now the schema:

```
const typeDefs = gql`
  type Person {
	  id: Int!
	  name: String!
	  email: String
  }
  type Query {
    person(id: Int!): Person
  }
`;
```

Let's have a closer look.

Since we already defined the structure of the data, we are pretty sure that what we will receive from the database will have this shape:

- id: Int! (an integer, non nullable)
- name: String! (a string, non nullable)
- email: String (a string, nullable)

The query `person(id: Int!): Person` wants an id as parameter (note the id is non nullable - it can't be null or we won't be able to retrieve anything!) and it returns a `Person` (an object defined by the Person type). Since it may happen the person we search for is not present in the database, the return type of this query is nullable (it can returns `null`).

Let's run the query in the Playground

```
query {
  person(id: 1) {
    id
    name
    email
  }
}
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/21x8tes80fdn39e4bzo5.png)

## Writing a new query

```
const typeDefs = gql`
  ...
  type Query {
    ...
    persons: [Person]!
  }
`;
```

```
const resolvers = {
  Query: {
    ...
    persons: (_, __, ___) => persons,
  },
};
```

Pretty straight-forward, right? The new query `persons` returns the whole `persons` array. Let's run the new query on the Playground

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oi6mosout7cpf13789y8.png)

## Writing a mutation

A `Mutation` is a function used to create, update and delete data in GraphQL. If you think at **CRUD**, mutations represent the C(reate) U(update) D(elete).

Let's create a new type `PersonInput` and another root type `Mutation`

```
const typeDefs = gql`
  ...
  input PersonInput {
    id: Int!
    name: String!
    email: String
  }
  type Mutation {
    createPerson(person: PersonInput!): Person
  }
`;
```

The function `createPerson` accepts a non nullable object of type `PersonInput` and returns another object of type `Person`. It's just a case the two types `Person` and `PersonInput` are the same.

The mutation then is something like

```
const resolvers = {
  ...
  Mutation: {
    createPerson(_, { person }, __) => {
      persons.push(person);
      return person;
    },
  },
};
```

For simplicity's sake we are entering manually the ID paying attention to not reuse the same ID twice (or the query `person` will unexpectedly return two results!).

Let's use the mutation on the Playground

```
mutation {
  createPerson(person: {id: 5, name: "Brock", email: "brock@gmail.com"}) {
    id
    name
    email
  }
}
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vzdvfjsmdo4lqfqxqrw6.png)

We can also run the `persons` query to see how the list of people is updated

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/uzrik9qur85oao6jymre.png)

Please remember that we are using an object as temporary database and that you will lose the data you add/change/remove via mutations once you restart the server! If you want some persistency, think about [connecting the GraphQL server to a data source](https://www.apollographql.com/blog/a-deep-dive-on-apollo-data-sources/). I won't do that in this article.

## Improving the code style with Prettier

Install Prettier with

```
npm install prettier --save-dev
```

Update your `package.json` file as follows

```
"scripts": {
  ...
  "prettier": "prettier --write ."
},
```

Create a file `.prettierrc.json` in the root folder of your project

```
{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true
}

```

This file contains the configuration of Prettier and the rules it will apply to your code.

Create a second file, `.prettierignore` and copy-paste the content of your `.gitignore`. This file will simply tell Prettier which files to ignore while formatting the code.

Now when you run `npm run prettier` it will apply the formatting rules to all files in the root directory and sub-directories. You can change this replacing

```
"prettier": "prettier --write ."
```

with

```
"prettier": "prettier --write ./src/**"
```

In this case Prettier will format files in the `src` folder and in its sub-folders.

## It's a wrap

That's it, you made it! Now you have a GraphQL server running locally and a very useful Playground to execute queries! :rocket:

Here's the repository with all the code we wrote in this article https://github.com/rossanodan/graphql-server-playground. Feel free to fork it and use it as your own or as a template.