Playing with GraphQL yoga and mongoose
Tags: graphql, graphqlyoga, mongodb
Published: 2018-12-22 04:18:02

---
title: Playing with GraphQL yoga and mongoose
published: true
description: Playing with GraphQL yoga and mongoose
tags: graphql, graphql-yoga, mongodb, 
---

This is going to be an introduction to using GraphQL yoga, which is a GraphQL server based on Express. 

If you don't know what GraphQL is, you might want to go through my [previous tutorial](https://dev.to/aurelkurtula/exploring-graphql-api-serve-3abf) where I use Express and GraphQL. That should get you up to speed. You could then learn how you can [create a movie website with GraphQL and React](https://dev.to/aurelkurtula/creating-a-movie-website-with-graphql-and-react-25d4) but not really required for you to understand this. We're simply recreating the first tutorial with different tooling. 

## Get started 

Let's set up the basic project. In an empty directory run these command lines

```
npm init -y
npm i -S graphql-yoga mongoose
touch index.js
```

The first line sets up the npm project, the second line installs the only two packages we will need, and to keep things simple, the entire code is going to go in `index.js`. Let's create a very basic structure:

```
const { GraphQLServer } = require('graphql-yoga');

const typeDefs = `
type Query {
  Greeting: String
}
`
const resolvers = {
  Query: {
    Greeting: () => `Hello World`
  }
}
const server = new GraphQLServer({
  typeDefs,
  resolvers
})

server.start({port: 7777}, () => console.log(`The server is running on port 7777`))
```

We required `graphql-yoga` at the top and run the server at the bottom. A GraphQL server needs us to define the type of queries it will be running, and the kind of data each query will respond with.

In our simple version, we have a query of `Greeting` that will return a string. And we specify that when the `Greeting` is called `Hello World` will be returned. 

Now, all we're left to do is run this in the terminal `node index.js`. I highly recommend you install `nodemon` but that's beyond the point. 

Now you need to run `http://localhost:7777` in a [graphql playground](https://github.com/prisma/graphql-playground) or use an [online graphql playground](https://www.graphqlbin.com/). Then just run the following query:

```
{
  Greeting
}
```

And you'll get the response `Hello World`.

## A bit deeper

Let's add an array of objects 

```
const typeDefs = `
type Query {
    People: [PeopleObject]!
    Greeting: String
}
type PeopleObject {
    id: ID
    first: String!
    last: String!
}
`
const resolvers = {
  Query: {
    Greeting: () => `Hello World`,
    People: () => [{first: 'Aurel', last: 'Kurtula'}]
  }
}
```

We've added `People` as a possible query. It has to return an array of objects, the properties of the object are defined in `PeopleObject`. Note the use of `!` makes those properties as required - meaning we have to return that content. 

Then we hard-coded an array which will be returned. 

In the playground, we could run this

```
{
  Greeting
  People{
    first
    last
  }
}
```

## Connecting to mongo database

In a [previous tutorial](https://dev.to/aurelkurtula/building-a-restful-api-with-express-and-mongodb--3mmh) I go through creating a mongo database from mlab. So follow that if you don't already have mongodb installed locally or if you don't know how to set up a mongo database. Then come back, still in `index.js` at the top add the following code.

```
const mongoose = require('mongoose');
const db = mongoose.connect('mongodb://localhost:27017/population');
const Schema = mongoose.Schema;
const peopleSchema = new Schema({
    first: { type: String  },
    last: { type: String}
})
const People = mongoose.model('people', peopleSchema)
```

If you have mongodb installed and running locally, the above would work out as is, if not you'll need to change the url which mongoose should connect to. `population` will be created automatically. Then we create a schema. Similar to what we did with Graphql, we need to tell mongoose what type of content will be added to the model, then we specify the model.

From this point forward, as you'll see, we interact only with the `People` model and the `people` model in the `population` database will be affected.

### Mongo and GraphQL

When we query `People` in the GraphQL playground we want the data to come from the mongo database and not from the array we hard coded. So let's change the `resolvers`

```
const resolvers = {
  Query: {
    Greeting: () => `Hello World`,
    People: () => People.find({}),
  }
}
```

There we are returning all the entries from the model in the database.

Cleary if we rerun the query in the playground we would get an empty array for `People` query as there's nothing in the database. 

Now we need to add to the database through GraphQL. For this we need to use mutations: 

```
const typeDefs = `
type Query {
  people: [People!]!
  person(id: ID!): People
}
type People {
    id: ID
    first: String
    last: String
}
type Mutation {
    createPerson(first: String!, last: String!): People
}
`
```

First, we specify the type; a mutation named `createPerson` it requires two properties and will return the `People` object. As usual, we need to specify the results of running that mutation, in `resolvers`

```
const resolvers = {
  Query: {....},
  Mutation: {
    createPerson: async (parent, args) =>{
        const newPerson = new People({
            first: args.first,
            last: args.last
        })
        const error = await newPerson.save()

        if(error) return error 
        return newPerson
    }
  }
}
```

Similar to other resolvers we want to do something when `createPerson` runs. This time we need to have access to the variables passed by the user, hence `args` (`parent` is beyond the scope of this tutorial).

First we create the `newPerson` object which we want to add to the database, then we create a new `People` module populated with the `newPerson` object, and finally, we save the object to the database, then we simply return the newly created object to graphQL server.

Back to the GraphQL playground

```
query people {
  Greeting
  People{
    first
    last
  }
}
mutation addingPerson{
  createPerson(first: "Gregor", last: "Samsa"){
    first
    last

  }
}
 
```

There, if you want to run the mutation you run `addingPerson` (by the drop-down menu). And, of course, after you add Gregor you can see the bugger :) when you run the `people` query. 

Finally, let's follow the same logic and add the ability to remove a person from the database.

First, specify the type `deletePerson`:

```
type Mutation {
    createPerson(first: String!, last: String!): PeopleObject
    deletePerson(id: ID!): PeopleObject
}
```

Then let's resolve it as yet another mutation: 

```
const resolvers = {
  ...
  Mutation: {
    createPerson: (parent, args) =>{...},
    deletePerson: (parent, args) => {
        return new Promise( (resolve, reject) => {
            People.findOneAndDelete(args.id, function(err, result){
                if (err) return err;
                resolve(result)
            })
        })
    }
  }

}
```

It's the exact same logic, mongoose gives us the ability to delete an object by its id - using `findOneAndDelete`. You can test `deletePerson` as follows:

```
mutation deleting{
  deletePerson(id: "5c1ccc3de652317c2c79d4ee"){
    first
    last
  }
}
```

And that is it for this tutorial.

You can get the code over at [github](https://github.com/aurelkurtula/Playing-with-GraphQL-yoga-and-mongoose). The code is divided into different files as it would in a fleshed out project