Backend part with ExpressJS, GraphQL and MongoDB for a basic Todo app
Tags: graphql, express, javascript, mongodb
Published: 2019-03-03 10:46:54

---
title: Backend part with ExpressJS, GraphQL and MongoDB for a basic Todo app
published: true
description: simple todo backend using express-graphql
tags: graphql, express, js, mongodb
---

## Here is the live version on [Glitch](http://glitch.com/edit/#!/join/e4cb8e25-6fda-4f77-8e2f-9ffaa9d9ccb7). (please make a remix before changing it)
# [Frontend part](https://dev.to/danielpdev/frontend-part-with-react-and-apollographql-for-a-basic-todoapp-4b19)
# Table of Contents

- [Table of Contents](#table-of-contents)
  - [What is graphql?](#what-is-graphql)
  - [Intro](#intro)
  - [Install prerequisites](#install-prerequisites)
  - [GraphQL types](#graphql-types)
  - [TodoType](#todotype)
  - [RootQueryType](#rootquerytype)
  - [MutationType](#mutationtype)
  - [Glueing code](#glueing-code)
  - [Starting Express GraphQL server](#starting-express-graphql-server)
  - [Testing queries and mutations](#testing-queries-and-mutations)
  - [Conclusion](#conclusion)

##What is graphql?
A query language used to define an API which provides a complete and understandable description of the data and enables powerful developer tools.
More on [Graphql](https://graphql.org/learn/).

## Intro
This is the backend part of a basic TodoApp using ExpressJS and GraphQL.
Our Backend will use express-graphql combined with mongoose and for the server we will use ExpressJS.
To access the live version on [Glitch](https://apollo-graphql-todo.glitch.me/graphql).
## Install prerequisites
Navigate to your projects directory and copy-paste the following commands:
```bat
mkdir todo-express-graphql && cd todo-express-graphql
npm install cors express express-graphql graphql mongoose
```
## GraphQL types
```bat
cd todo-express-graphql && mkdir schema && cd schema && touch todo_type.js
```

## TodoType
```js
const mongoose = require('mongoose'); 
const graphql = require('graphql'); //package used to build our graphql schema
const {
  GraphQLObjectType,
  GraphQLID,
  GraphQLInt,
  GraphQLString
} = graphql; //necessary types for defining our schema

const TodoType = new GraphQLObjectType({
  name:  'TodoType',
  fields: () => ({
    id: { type: GraphQLID },
    likes: { type: GraphQLInt },
    content: { type: GraphQLString },
  })
}); 

module.exports = TodoType;
```
When we define a type for our GraphQL schema we need to create an instance of `GraphQLObjectType` and pass an object with the required fields for our type. <br/>
`name` is the only required field on a `GraphQLObjectType`. <br/>Some of the most commonly used properties that we will cover later in this post are `fields`, needed to define the attributes that this type resolves to and `resolve` function. 
Please refer to official graphql documentation regarding [GraphQLObjectType](https://graphql.org/graphql-js/type/#graphqlobjecttype)


### RootQueryType
```js
const mongoose = require('mongoose');
const graphql = require('graphql');
const { 
  GraphQLObjectType,
  GraphQLList,
  GraphQLID,
  GraphQLNonNull
} = graphql;
const Todo = mongoose.model('todo');
const TodoType = require('./todo_type');

const RootQueryType = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: () => ({
    todos: {
      type: new GraphQLList(TodoType),
      resolve() {
        return Todo.find({});
      }
    },
    todo: {
      type: TodoType,
      args: { id: { type: new GraphQLNonNull(GraphQLID) } },
      resolve(parentValue, { id }) {
        return Todo.findById(id);
      }
    }
  })
});

module.exports = RootQueryType;
```
`RootQueryType` has all the root endpoints needed for consuming our Todo resource. Here we are defining the `todos` endpoint as a response which will contain a list of `TodoType` documents by using `GraphQLList(TodoType)`. Next is our `todo` endpoint used for retrieving a 
single todo from our database.<br/>
`GraphQLNonNull` is used because we need to make sure that our `id` received as query param is not undefined.
<br/>`resolve(parentValue, { id })` first argument that resolve function receives is the parentValue or root which is the value passed down from other types. This argument enables the nested nature of GraphQL queries.
 The second argument is the object with the actual query params.<br/>
What's nice about express-graphql is that always expects a promise to be returned from a resolver function and using mongoose will integrate 
really smoothly.
More on [resolvers](https://www.apollographql.com/docs/graphql-tools/resolvers.html#Resolver-function-signature) from ApolloGraphQL documentation.

### MutationType

Mutations are typically used to alter data from our database and you can see that they are very similar with our `RootQueryType`, except that now we are altering data based on query params.

```js

const graphql = require('graphql');
const { GraphQLObjectType, GraphQLString, GraphQLID } = graphql;
const mongoose = require('mongoose');
const Todo = mongoose.model('todo');
const TodoType = require('./todo_type');

const mutation = new GraphQLObjectType({
  name: 'MutationType',
  fields: {
    addTodo: {
      type: TodoType,
      args: {
        content: { type: GraphQLString }
      },
      resolve(parentValue, { content }) {
        return (new Todo({ content })).save()
      }
    },
    likeTodo: {
      type: TodoType,
      args: { id: { type: GraphQLID } },
      resolve(parentValue, { id }) {
        return Todo.like(id);
      }
    },
    deleteTodo: {
      type: TodoType,
      args: { id: { type: GraphQLID } },
      resolve(parentValue, { id }) {
        return Todo.remove({ _id: id });
      }
    },
    updateTodo: {
      type: TodoType,
      args: { id: { type: GraphQLID }, content: { type: GraphQLString }  },
      resolve(parentValue, { id, content }) {
        return Todo.update({ _id: id }, { content });
      }
    },
  }
});

module.exports = mutation;
```
### Glueing code
```js
const graphql = require('graphql');
const { GraphQLSchema } = graphql;

const query = require('./root_query_type');
const mutation = require('./mutations');

module.exports = new GraphQLSchema({
  query,
  mutation
});

```
Most of the times when you'll be writing your schema files you'll have to pass an object with two keys: `query` and `mutation`. Pretty simple and straightforward, just import the needed mutations and queries
and pass them as an object to `GraphQLSchema`.<br/>
More on [GraphQLSchema](https://graphql.org/graphql-js/type/#graphqlschema)

## Starting Express GraphQL server
```js

const express = require('express');
const expressGraphQL = require('express-graphql');
const mongoose = require('mongoose');

const todoModel = require('./models/todo');
const bodyParser = require('body-parser');
const schema = require('./schema');
const cors = require('cors')
const app = express();
app.use(cors());

const MONGO_URI = 'your mLab link';
if (!MONGO_URI) {
  throw new Error('You must provide a MongoLab URI');
}

mongoose.Promise = global.Promise;
mongoose.connect(MONGO_URI);
mongoose.connection
    .once('open', () => console.log('Connected to MongoLab instance.'))
    .on('error', error => console.log('Error connecting to MongoLab:', error));  

app.use(bodyParser.json());
app.use('/graphql', expressGraphQL({
  schema, //pass the schema to our middleware 
  graphiql: true //enable graphiql interface so we can test our queries and mutations before starting to use it.
}));

app.get('/', (req, res) => {
  res.redirect('/graphql');
});

app.listen(4000, () => {
  console.log('Listening at 4000');
});
```
## Testing queries and mutations
When you have to build a query and you don't know exactly how to write it 
then `graphiql` is going to help https://apollo-graphql-todo.glitch.me/graphql.
One of the powers of GraphQL is instant documentation. After we've defined the types that are going to be used in our `GraphQLSchema` we have a documentation ready. Just access https://apollo-graphql-todo.glitch.me/graphql and on the top right you can find the `Docs`.
<br/>
## Writing queries in graphiql:
```js
query{
  todos{
    id
    likes
    content
  }
}
```
This query is going to be run on our `RootQueryType` and `todos` 
field is going to be resolved to a list of `TodoTypes`. `TodoType` contains 
an `id`, `likes`, `content` as properties and because we have a list, we will get back a response that looks like this: 
```js
{
  "data": {
    "todos": [
      {
        "id": "5c5c21184c9edc006857c11b",
        "likes": 17,
        "content": ""
      },
      {
        "id": "5c5c26e84c9edc006857c124",
        "likes": 4,
        "content": "asd"
      },
      {
        "id": "5c5c29b296f75b0068f3b9db",
        "likes": 0,
        "content": "asdad"
      },
      {
        "id": "5c5c29c296f75b0068f3b9dc",
        "likes": 0,
        "content": "eq123"
      }
    ]
  }
}
```

As an exercises, try to modify Add, Modify and Delete a Todo.

##Conclusion

Express-graphql is a great tool for developing backends that need to support GraphQL and now we've seen how easily it can be integrated with MongoDB. We now have a small example of how you could implement some basic queries and mutations.

I hope you have enjoyed this article.