Full Stack React — Part 2(React, GraphQL, Express, MongoDB)

Episode 2: Getting to know GraphQL (Evernote Clone)

Photo by Clément H on Unsplash

In this episode, we will get ourselves familiar with GraphQL (schemas, resolvers, queries) before diving into building out our schema.

Agenda:

  • Review what? why? and how? related to GraphQL
  • Setup GraphQL
  • Create dummy data (array of objects)
  • Build schema for this dummy data
  • Create resolvers
  • Test our queries with built-in GraphiQL (similar to Postman is to REST)

Review the What? Why? How?

  • What is GraphQL? GraphQL is a syntax that describes how to ask for data, instead of using multiple endpoints GraphQL uses one main endpoint (ex: /graphql)that you ask for data.
  • Why use GraphQL? It limits the requests we need to make to the server which saves time on the performance. It uses one main endpoint to query from, and you only get the data back that you asked for.
  • How do we use it? Creating a GraphQL api consist of using (schemas, queries, and resolvers)

Setup GraphQL

First things first, you should already have graphql express-graphql installed in your package.json file from Part 1 of this series, your dependencies should look like this right now.

"dependencies": {"express": "^4.17.1","express-graphql": "^0.8.0","graphql": "^14.4.1","nodemon": "^1.19.1"}

I’ll do a quick explanation on what the graphql and express-graphql packages does.

graphql — allows us to use all the methods and properties GraphQL has inside our app

express-graphql — enables us to work with Express and GraphQL together with ease.

Now let’s get to some code!

STEP 1: Inside our server.js file add the following code

// sets up our graphql server
const graphqlHTTP = require('express-graphql')
// grabs buildSchema method from graphql, this will help us build out our schema
const { buildSchema } = require('graphql')

Go ahead and make sure your server is running with nodemon, in the terminal run command yarn startor npm start

still in your server.js file, let’s create the GraphQL server now.

app.use( "/graphql", graphqlHTTP({schema: ourSchema,rootValue: resolvers,graphiql: true}),);
  • The schema field is set to “ourSchema” (named this in advanced).
  • The rootValue field is set to “resolvers” (named this in advanced).
  • The graphiql field is set to true that way we can use this tool to test out our queries.

STEP 2: Create our dummy data to work with, which is just an array of objects that we can add to, read from and delete from.

const data = [{    id: 1,   firstname: "tim",   lastname: "allen"},{   id: 2,   firstname: "Brad",   lastname: "Pitt"}];

Before we dive deep into creating schema, queries, and resolvers we first need to understand what they are. In GraphQL there are many different types you can use to describe your schema

  • Schemas are ways to describe the structure of what are data is going to look like
  • Queries are the data you want to grab, from a URL point of view this is what it would look like to request data from the people endpoint Ex1:localhost:5000/graphql?query=people queries will describe what it should return. Ex2: localhost:5000/graphql?query=students just by looking at this, the query seems that it would describe what students should return (maybe an array of objects)
  • Mutations describe how you want to modify the data. Ex: creating a person for our dummy data, deleting a person from our dummy data.
  • A resolver is an object of functions (with the same name as the queries) that actual return the data that you described *we will look more into this in code so don't worry if it's confusing.

STEP 3: Let's start with queries when building our schema. Queries are defined as field:value below the dummy data, create our schema.

const schema = buildSchema(`// what URL looks like localhost:5000/graphql?query=peopletype Query{
people: [Person] -> it should return array of person(objects)
}
`);

let's expand on this and create a data type that describes what Person looks like

const schema = buildSchema(`// what URL looks like localhost:5000/graphql?query=peopletype Query{
people: [Person] -> it should return array of person(objects)
}
// we are describing what the Person object looks like, the fields are (id, firstname, lastname) and the values it has.type Person {
id: ID,
firstname: String,
lastname: String
}
`);

STEP 4: let’s create a resolver that actually returns the data we described

// now, when we request localhost:5000/graphql?query=people it will return our dummy dataconst resolver = {
people: () => data
}

Now would be a good time to test these queries out!

STEP 5: (with the server running) Go to your browser and type localhost:5000/graphql you should see this

we will use this to test out our queries, ignore that error its nothing ;)

let’s try querying for some data, right now we only have the people query to access. We now have access to all the fields that it has.

{
people {
id,
firstname
}
}

Type this into the GraphiQL editor and you should get the dummy data back, as we specified in our resolver. *Check back to STEP 4 for a refresher*

STEP 6: For good practice, let's create a mutation to modify(add a person) our dummy data

const schema = buildSchema(`// what URL looks like localhost:5000/graphql?query=peopletype Query{
people: [Person] -> it should return array of person(objects)
}
// we are describing what the Person object looks like, the fields are (id, firstname, lastname) and the values it has.type Person {
id: ID,
firstname: String,
lastname: String
}
input personInput {
firstname: String,
lastname: String
}
type Mutation {
addPerson(input: personInput): Person
}
`);

Input is also like a type without specifying the “type” in front of it. You need to give this input a name to reference by. Think of it as we are specifying what text-fields this input will have, in our case firstname and lastname

we created a mutation called addPerson it takes in a param called input we pass in the personInput object as data. Therefore, the data we pass in for the personInput from our mutation is going to return a Person object with that data. Huh? no worries we will test this code in a bit ;)

STEP 7: Let's create a resolver for this mutation, inside our same resolver object

// now, when we request localhost:5000/graphql?query=people it will return our dummy dataconst resolver = {
people: () => data,
addPerson: ({input}) => {
const person = {
id: data.length + 1,
firstname: input.firstname,
lastname: input.lastname
}
data.push(person)
return person
}

}

Let’s run down this code, we did some destructuring({input}) and grabbed the input straight from the param we passed in the mutationaddPerson(input: personInput) that input has access to the firstname and lastname we specify. Therefore, when we create a new person object whatever values we pass in for the fields firstname and lastname is going to create that person and push that object to our dummy array from earlier. Since we said that theaddPerson mutation was going to return a person object addPerson(input: personInput): Person, it does return a person object in the resolver.

Whew! that was a lot, lets test this code out in GraphiQL to get a better look.

STEP 8: In your browser, in your GraphiQL editor run this →

mutation{  addPerson(input: {firstname: "billy", lastname: "bob"}){
id,
firstname
}
}

This should return an object(just like we said in the resolver) with your newly created person and you only want the id and firstname of that person you created. Remember this pushes the object to our dummy data as well, check your people query as well

{
people{
firstname,
lastname
}
}

Again, this should return our dummy data with a new object that you created.

I’m going to end this tutorial here in hopes you guys got that working for you :) and please I’d advise playing around with the data to get really familiar with how GraphQL works. This was a strategy to get our feet wet. Feel free to read further documentation on the subject.

Resources used

HowToGraphQL — detailed tutorials on using GraphQL for the frontend and backend

Docs — explains everything of course ;)

TutorialsPoint — another great resource that explains GraphQL in detail.

In case you missed Part 1 here is the link

if you would like to watch the video version of this process feel free to check it out here

Hope you guys enjoy, more to come! :)

--

--

--

A passionate web developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

All about JavaScript Function

Linked Lists for Beginners who know Javascript Trees

JavaScript Number & Math

How To Reduce Angular Deployment Times by Disabling Differential Loading

Servers

Using Proxyquire with Nested Dependencies

Better architecture for integrating analytics into React/Redux using RxJS.

ARRAY FUNCTIONS IN JAVASCRIPT

Best Practices To Implement The Snippet In AB Testing Tools

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ajea Smith

Ajea Smith

A passionate web developer

More from Medium

Why Should I Use Node.js?

Blog Article 03 — NodeJS

Node Js Overview

Introduction to NodeJS