Get a GraphQL server up and running in 5 minutes using graphql-yoga and mongoose

Written by gelens.imre | Published 2018/03/14
Tech Story Tags: graphql | nodejs | mongoose | mongodb | graphql-yoga | latest-tech-stories | graphql-server-set-up | graphql-yoga-and-mongoose

TLDR This article is no longer longer updated and I CANNOT RECOMMEND THIS APPROACH. It is a simple tutorial on GraphQL to get started using the GraphQL-yoga package. The project is a package to use GraphQL with databases. Mongo currently is not supported yet, but they are working on it. This will probably make things even simpler. The tutorial is aimed at creating a web shop with a database containing our products that we want to be offering. The simple scenario is that we are creating a database with a name, an image, a description and a price.via the TL;DR App

THIS ARTICLE IS NO LONGER UPDATED AND I CANNOT RECOMMEND THIS APPROACH
For some time now, I have been reading a lot about GraphQL but never got round to actually checking it out. It sounded like the next hype and yet another thing to implement and learn. However, I gave it a try this morning and after piecing together the scattered documentation I am completely hooked. Because I had trouble finding a simple tutorial that covered the basics I am documenting what I found here in what hopefully will be the most simple way of getting started with graphql. If I got your attention please read on. I promise that you will have a server with database up and running in 5 minutes (provided that you already have a mongodb database running).

The structure of your application

Like the title may suggest we are going to use graphql-yoga to get started. Because this package abstracts away a huge amount of the setup we only need three things to get our app running:
  1. A set of types. Types are object definitions. They tell the GraphQL server what to return when we ask for a certain object.
  2. A set of resolvers. Resolvers are functions that get called when data is requested from one of the types.
  3. A mongoose model to query the data on our database.
Two types of operations are used. Queries and Mutations. These are pretty self explanatory. Here we will only focus on querying. In my experience once you get one full flow working, the rest will be easy. So let’s code.

Setting up

Create a package.json like below and run
npm install
on the folder. This will install some babel presets for ES6 and Async/Await together with the mongoose and graphql-yoga packages.
{
  "name": "tutorial-graphql",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon ./index.js --exec babel-node",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Imre Gelens",
  "license": "ISC",
  "dependencies": {
    "graphql-yoga": "^1.13.1",
    "mongoose": "^5.0.17"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-plugin-syntax-async-functions": "^6.13.0",
    "babel-plugin-transform-regenerator": "^6.26.0",
    "babel-preset-es2015": "^6.24.1",
    "nodemon": "^1.17.4"
  }
}
Also we need to add a .babelrc file with the following contents.
{
	"presets": [
		"es2015"
	],
	"plugins": [
		"syntax-async-functions",
		"transform-regenerator"
  ]
}
That’s it. We are ready to go.
Creating the mongoose schema
We are going to work from database to endpoint, so we are starting with creating a mongoose model to query our database. The simple scenario is that we are creating a web shop and have a database containing our products that we want to be offering. The products have a name, an image, a description and a price. To get this from the database our model definition will look something like this:
import mongoose from "mongoose";

const Schema = mongoose.Schema;

const productSchema = new Schema({
    name: {type:String},
    description: {type:String},
    image: {type:String},
    price: {type:Number}
}, {collection:"products"}); // Defining the collection is redundant in this case. 

const products = mongoose.model('products', productSchema);

Creating the types

Now we are going to create the types. We need two types. One for our product data and one defining the query that we want to call based on our products. That all looks something like this:
const typeDefs = 
`type Product {
  _id: String
  name: String
  description: String
  image: String
  price: Float
}

type Query {
  product(_id: String): Product
  products: [Product]
}`
Notice how the query uses the Product type when the plural products query is called. This returns a list of our product type definition.

Creating the resolvers

Lastly, we want to add our resolvers. The only thing that these functions need to do is to query our mongo database through our created mongoose model. That will look like this:
const resolvers = {
  Query: {
    product: async (_id) => {
      return (await products.findOne(_id))
    },
    products: async () => {
      return (await products.find({}))
    },
  },
}

Putting it all together

When we put this all together we have the result below:
import { GraphQLServer } from 'graphql-yoga'
import mongoose from "mongoose"

const connection = mongoose.connect('mongodb://my_awesome_db')

const Schema = mongoose.Schema;

const productSchema = new Schema({
    name: {type:String},
    description: {type:String},
    image: {type:String},
    price: {type:Number}
}, {collection:"products"}); // Defining the collection is redundant in this case. 

const products = mongoose.model('products', productSchema);

const typeDefs = 
`type Product {
  _id: String
  name: String
  description: String
  image: String
  price: Float
}
type Query {
  product(_id: String): Product
  products: [Product]
}`

const resolvers = {
  Query: {
    product: async (_id) => {
      return (await products.findOne(_id))
    },
    products: async () => {
      return (await products.find({}))
    },
  },
}

const server = new GraphQLServer({ 
  typeDefs, 
  resolvers 
})

server.start(() => console.log('Server is running on localhost:4000'))
Save this to index.js and run it using
npm run dev
 . If you go to http://localhost:4000 you will find your playground where you can test the queries.
If all is well this will already return results. Basically you have created a backend which fits on an A4 sheet of paper which already serves content from a database. Well done!

Final notes

The project https://github.com/graphcool/prisma is a package to use GraphQL with databases. Mongo currently is not supported yet, but they are working on it. This will probably make things even simpler.
Next op is defining Mutations to also update or delete your products. For help with this you can check docs below. Seems pretty easy to piece together. Happy coding!

Published by HackerNoon on 2018/03/14