Photo by Wes Hicks / Unsplash

GraphQL is a query language for APIs that makes it easier to extract data from a  data source. With the high adoption of Software oriented architecture, here are some use cases where you could need GraphQL:

  • You have various clients that need differents data
  • You are fetching more than you need or less than you need.
  • You make multiples call to fetch data that are linked between them
  • You want auto-generated documentation from the GraphQL schema
  • Built-in type checking and validation of the input
  • Supported by the most popular programming languages
  • A large community building tools around to make the usage easier

We will see how to set up a GraphQL server in Node.js using Apollo server 3 who provides great features compared to the previous version.

Setup the project

To start, we will use a boilerplate for the Node.js project we built on this tutorial.

git clone node-graphql

cd node-graphql

yarn install

yarn start

Now the project work as expected, let's install libraries required to create a GraphQL server:

yarn add apollo-server graphql

Define the GraphQL schema

We will build a simple system to register users and browse. Let's create a file called schema.ts and add the GraphQL schema.

import { gql } from 'apollo-server';

const typeDefs = gql`
  type User {
    id: ID!
    firstName: String!
    lastName: String!
    email: String!
    password: String!

  input CreateUserInput {
    firstName: String!
    lastName: String!
    email: String!
    password: String!

  type Mutation {
    registerUser(input: CreateUserInput!): User!

  type Query {
    users: [User!]!

export default typeDefs;

Here, we define the schema for the User then, create a mutation to register a user, and finally define a query to retrieve users. Before writing the resolvers for the mutation and the query, we will first generate types definition from the GraphQL schema.

Generate type definitions

GraphQL code generator is a CLI tool that generates types definitions from the GraphQL schema. It avoids us writing the same types which are already described by the GraphQL schema. So, once we change the schema, we will run a command to update the definition of the auto-generated types. For that, we need three Node packages:

  • graphql-codegen/cli: command-line tool for the code generator.
  • graphql-codegen/typescript: generate types definitions from the schema.
  • graphql-codegen/typescript-resolvers: generate the method signature for a resolver.
yarn add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers

We only need them during our development; this is why they are installed as devDependencies.

We use a configuration to indicate to codegen where our schema is located and where we want the output to be generated. Let's create a file named codegen.yml at the project root directory, then add the code below:

overwrite: true
schema: src/schema.ts
documents: null
      - "typescript"
      - "typescript-resolvers"

The property schema takes the location of our GraphQL schema, and we want the output to be stored in src/types/types.d.ts.

Run the command below to generate the types:

yarn graphql-codegen

Check the file generated but don't edit anything inside, and if it happens and you don't know how to go back, just retype the code above to regenerate.

Create our dataset

Apollo can fetch data from various data sources like database, REST or GraphQL API, RPC, and static data. To focus on GraphQL, we will create a file that will act as our data source with some existing users by default.

Create a file datasource.ts and add the code below:

export default [
    email: '',
    firstName: 'Tywin',
    id: '1',
    lastName: 'Lannister',
    password: 'my-very-secured-password',
    email: '',
    firstName: 'Lyanna',
    id: '2',
    lastName: 'Mormont',
    password: 'my-very-secured-password',

Create resolvers for the mutation and query

Create a file resolvers.ts and add the code below:

import { CreateUserInput, MutationResolvers, QueryResolvers, Resolvers } from './types/types';
import datasource from './datasource';

const createUser: MutationResolvers['registerUser'] = (parent, args) => {
  const { email, firstName, lastName, password }: CreateUserInput = args.input;

  const user = {
    id: `${datasource.length + 1}`,


  return user;

const findAllUsers: QueryResolvers['users'] = () => {
  return datasource;

const resolvers: Resolvers = {
  Mutation: {
    registerUser: createUser,
  Query: {
    users: findAllUsers,

export { resolvers };

Create GraphQL server with Apollo server 3

Replace the content of the index.ts with the code below:

import { ApolloServer } from 'apollo-server';
import resolvers from './resolvers';
import typeDefs from './schema';

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

server.listen().then(({ url }) => {
  console.log(`🚀  Server ready at ${url}graphql`);

Start the server by running yarn start. Navigate to http://locahost:4000/graphql. You got this page:

Click on the button Query your server; you will be redirected to the Apollo sandbox, which is an editor where you can execute your graphQL queries:

The Sandbox UI includes:

  • An Operations panel for writing and executing queries (in the middle)
  • A Response panel for viewing query results (on the right)
  • Tabs for schema exploration, search, and settings (on the left)
  • A URL bar for connecting to other GraphQL servers (in the upper left)

Note: if the environment variable NODE_ENV is set to productionIntrospection is disabled by default. You will need to enable it manually so that Apollo sandbox can query the schema definition.

To do that, update the Apollo Server instance creation to this:

const server = new ApolloServer({ 
  introspection: true

We reached the end of this tutorial, we saw how to set up a GraphQL server with Apollo server 3. To go further checkout the Apollo documentation

Find the final source code on the GitHub repository.

Follow me on Twitter or subscribe to my newsletter to not miss the upcoming posts.