Setting Up A Graphql Server With Node + Graphql-Yoga + Prisma

Gbolahan Olawuyi
11 min readSep 6, 2019

--

What you will learn

  1. Introductory knowledge on GraphQL
  2. How to setup GraphQL server with GraphQL-Yoga
  3. How to setup Prisma and query your database
  4. Build a mini note taking application with CRUD functionalities

What is GraphQL

GraphQL is a query language for api that helps to unify data requirements from multiple clients which can be mobile, web, desktops and a long range of other devices.

Prior to GraphQL there was REST which is the most common way of getting data from a server. Usually your clients sends a requests to the server, the server interacts with a database and then responds with data to the client.

What we have with rest

  1. Several round trips to the server to fetch data
  2. Server responds with a lot of redundant data
  3. Data is gotten from multiple URLs

What we have with GraphQL

  1. Declarative data fetching
  2. Exposes a single endpoint
  3. GraphQL queries always returns a predictable result
  4. Gets data in a single request
Photo Credit: devopedia.org

Project setup

Create a new empty project folder called note-app run

mkdir note-app

Now run npm initwhich will initialize the directory wih a package.json

Now we will install the packages we need run

npm i graphql-yoga nodemon

PS: nodemon is a tool that helps us monitor our application for changes and automatically restarts the application

Create a new folder src inside the note-app folder then inside the folder create a file index.js, your file structure should look like this

Open package.json and add

“start”: “nodemon -e js,graphql src/index.js”

This tells nodemon to watch all files ending with .js and .graphql extension and then start the server.

Creating A Graphql Server With GraphQL-Yoga

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

const typeDefs = `
type Query {
hello: String!
}
`

const resolvers = {
Query: {
hello: (_, args, context, info) => {
return "Hello World";
},
}

const server = new GraphQLServer({ typeDefs, resolvers })
server.start(() => console.log('Server is running on localhost:4000'))

First we make sure that GraphQLServer is imported from the graphql-yoga package.

typeDefs is a required argument and should be a Schema Definition Language (SDL) string which is used to describe the schema. A GraphQL schema describes the functionality available to the clients which connect to it. Schema Definition Language (SDL) is the syntax for writing GraphQL Schemas. It is otherwise known as Interface Definition Language.

The GraphQL schema provides a clear contract for client-server communication. @nikolasburk

resolvers. A resolver is a function that connects schema fields and types to various backends. Resolvers provide the instructions for turning a GraphQL operation into data. It can retrieve data from or write data to anywhere, including a SQL, No-SQL, or graph database, a micro-service, and a REST API. Resolvers can also return strings, ints, null, and other primitives.

Next we instantiate a GraphQLServer instance and pass our typeDefs and resolvers as an object after which we then call the start() method on the server

now run npm startyou’ll see the output

Server is running on localhost:4000

now goto http://localhost:4000 in your browser, you will see the following result

In the query editor type the following code

query {
hello
}

Next click on the play button to execute the query you will see the following result.

Kicking It Up A Notch

Now that was easy, let’s implement a more sophisticated example.

const { GraphQLServer } = require('graphql-yoga')const posts = [  {    id: 1,    title: 'Article one',    content: 'This is Article One'  },  {    id: 2,    title: 'Article Two',    content: 'This is Article Two'  },  {    id: 3,    title: 'Article Three',    content: 'This is Article Three'  }];const typeDefs = ` type Query {  post(postId: Int!): Post  allPosts: [Post!]!}type Post {   id: Int   title: String   content: String }`const resolvers = { Query: {    post: (_, { postId }, context, info) => {     return posts.filter(post => post.id === postId)[0];    },    allPosts: (_, args, context, info) => {     return posts;    }  },}const server = new GraphQLServer({ typeDefs, resolvers });server.start(() => console.log('Server is running on localhost:4000'));

From the code above, we defined a Post type with 3 fields describing what our posts should look like

Next we defined two query actions to fetch a post by id and also to get all the posts from the posts array as we don’t have a database yet

In our resolvers query object, we connect our post and allPosts function to the post and allPosts fields in the Query type.

Using The GraphQL Api

That was easy right, now lets retrieve a post by id. type the following

query {
post(postId: 1){
id
title
content
}
}

Your result should look like this

Notice that, the query requires a parameter (postId) which we pass to the post query and it filters through and return the specific posts.

We also explicitly stated the data we wanted from the api id, title, content

Type the following query in your browser, and click on the execute button

query {
posts{
id
title
content
}
}

You should see the following

GraphQL Mutations

Mutations are like queries, you must define them in your Schema the difference is that you define queries in the Query type and mutations in the Mutation type. Also Mutations let you Create, Update and Mutate data.

Add the code below to your typeDefs, our new mutation has a field addPost which exepects two parameters, title and content

type Mutation {addPost(title: String!, content: String!): Post}

Add the code below to your resolver

Mutation: {addPost: (_, { title, content }, context, info) => { const newPost = {     id: 4,     title,     content   }   posts.push(newPost)   return newPost;  }}

Save the code and our server should automatically restart. In the GraphQL playground, type the following.

mutation{
addPost(title: "Article Four", content: "This is Article Four"){
id
title
content
}
}

Your should now see

Great now we have a fundamental understanding of some GraphQL operations Query and Mutation at this point you must be wondering, how then do i interface this with a database? you can make use of literally any database orm like sequelize, mongoose etc. but this is where prisma comes in.

Prisma bridges the gap between your database and GraphQL resolvers. It replaces traditional ORMs and makes it easy to implement resilient, production-ready GraphQL servers. prisma.io

Photo Credit: prisma.io

Setting Up Prisma

First ensure to create an account with prisma, then install the prisma cli

npm install -g prisma

now change into the note-app directory and run

prisma init

Select Demo Server + Mysql database, this will require authentication thus the reason why you should create and account.

Next up, choose the region of the server with the lowest latency

The next options are easy to follow,

  • choose the name of the service(note-app)
  • Name of your stage(dev)
  • select the programming language for the generated Prisma client, here make sure to choose Don’t generate

You result should look like this

Now we have two new files in our note-app directory prisma.yml and datamodel.prisma

prisma.yml is the root configuration file for a Prisma service. Every Prisma service is defined by exactly one prisma.yml. You can think of prisma.yml as a template for one Prisma service.

datamodel.prisma is the foundation for the GraphQL API of your Prisma service. Based on the data model, Prisma will generate a powerful GraphQL schema (called Prisma database schema) which defines CRUD operations for the types in the data model. check out this article

open up prisma.yml and add the following

generate:  
- generator: graphql-schema
output: ./src/generated/prisma.graphql

this tells prisma to download the Prisma GraphQL schema and store it in `./src/generated/prisma.graphql`

now open up datamodel.prisma and replace the content with this

type Note {  id: ID! @id  title: String!  content: String!}

This specifies a Note type which will be mapped to a database table with 3 fields id , title , and content

now run the following in your console

prisma deploy

Great you’ve now successfully setup Prisma. If you look into ./src/generated/prisma.graphql file generated by Prisma, you’ll see that Prisma has generated all of the CRUD functionalities we need as well as a tonne of other code, amazing right.

next up we will install prisma-binding which will enable us query our database for data.

npm i prisma-binding

open up index.js and import Prisma from prima-binding

const { Prisma } = require('prisma-binding')

next up modify you server variable to look like the following

const server = new GraphQLServer({    typeDefs: './src/generated/prisma.graphql',    resolvers,    context: {      db: new Prisma({        typeDefs: './src/generated/prisma.graphql',
endpoint: '__PRISMA_ENDPOINT__'
}) }});

the typeDefs specified in our GraphQLServer and Prisma instance, tells it to make use of the generated Prisma GraphQL

ps: the endpoint is specified in your prisma.yml file

context: is an object that gets passed through to the resolver, it enables the resolver to be able to share information. We are going to pass a db object which represents our Prisma instance so we can query data from our database. Think of this instance as a sort of database connector.

Querying Our Database For Data

modify your resolver object to look like the following

const resolvers = {Query: {    notes: async (_, args, context, info) => {    const notes = await context.db.query.notes(null, info);    return notes;   }  }}

we made use of the db property available on the context object to query our database for all the notes.

now open your browser and type the following query

query{
notes{
id
title
content
}
}

Your result should be the following

there’s no note currently in our database, lets create some notes

Mutation With Prisma: Creating a New Note

Modify your Mutation object to look like the following.

Mutation: {    createNote: async (_, args, context, info) => {    const note = await context.db.mutation.createNote({    data: {      title: args.data.title,      content: args.data.content    }}, info);    return note;    }}

now open up your browser and type the following

mutation{
createNote(data: {
title: "First Note",
content: "First Note content"
}) {
title
content
}
}

Your result should be the following

Now that we have a note in our database, let us write a query for a single note. add the following to your Query object

note: async (_, args, context, info) => {    const note = await context.db.query.note({      where: {      id: args.where.id    }    }, info);    return note;}

In your browser type the following

query{
notes{
id
}
}

this will return all the notes with their ids, in our case there’s only one post

now copy the id and execute the query below

query{
note(where: {
id: "cjzr2xrmrr6cw0b530jsnf3c7"
}) {
id
title
content
}
}

Your result should be the following

Mutations With Prisma: Updating A Note

Add the following code below to your Mutation object

updateNote: async (_, args, context, info) => {const note = await context.db.mutation.updateNote({    where: { id: args.where.id },    data: {      title: args.data.title,      content: args.data.content      }    }, info)    return note;}

now type this in your GraphQL Playground, this will update the note data with the specified id.

mutation{
updateNote(where: {
id: "cjzr2xrmrr6cw0b530jsnf3c7"
}, data: {
title: "First Title Update",
content: "First Content Update"
}) {
title
content
}
}

your result should be the following

Mutation With Prisma: Deleting A Note

Add the following to your Mutation object

deleteNote: async (_, args, context, info) => {const note = await context.db.mutation.deleteNote({    where: { id: args.where.id }    }, info)    return note;}

The code above deletes a note with the a specific id.

now type the following in your GraphQL playground

mutation{
deleteNote(where:{
id: "cjzr53vdtsxe30b53s0hazs7w"
}){
id
title
content
}
}

Your result should be the following

Conclusion

In this tutorial you’ve learnt how to setup your own GraphQL server with Node.js and GraphQL-Yoga, you also learnt how to query data from a database using Prisma. We built a simple note taking app, you can kick it up a notch by building other apps leveraging the knowledge you just acquired.

Overall we saw how using GraphQL can easily boost our API development time by leveraging it’s declarative nature and by so doing it makes it easy for our clients to be able to request for just the data they need.

Hope you learnt a lot……Kudos.

Link to the repo

Here are some useful resources for futher learning

References

--

--