DEV Community

Cover image for A Journey with GraphQL
Ryan Doyle
Ryan Doyle

Posted on • Edited on

A Journey with GraphQL

GraphQ What?

Before I started with GraphQL I heard about it on a number of posts and podcasts, all describing how great it was. I never really understood what it was all about, but I understood people were excited about it. So, why should I be interested?

Before we go into what GraphQL is, it's probably beneficial to look at a traditional REST API. I once made a workout API for a little project on freecodecamp.com. It had a simple frontend that allowed you to create a user, add an exercise, and lookup the user and exercises based on their user id. Below is the code for the request to retrieve a user:

app.get('/api/exercise/log/:user', async (req, res) => {
  const user = await User.findById(req.params.user).populate('exercises'); 

  const to  = req.query.to || moment().format(); // set to current day if no entry
  const from  = req.query.from || moment(0).format(); // set to 1970 if no from
  const totalExercise = user.exercises.length;
  let exercises;

  if (req.query.limit) {
    exercises = await Exercise.find({ userId: req.params.user }, '_id description duration date')
      .where('date')
      .gte(from)
      .lte(to)
      .limit(parseInt(req.query.limit))
  } else {
    exercises = await Exercise.find({ userId: req.params.user }, '_id description duration date')
      .where('date')
      .gte(from)
      .lte(to)
  }

  const response = {
    userId: user._id,
    username: user.username,
    totalExercises: totalExercise,
    exercises: exercises
  }
  res.json(response)
})
Enter fullscreen mode Exit fullscreen mode

Looking at this gives me such pain now! When I first wrote this, I essentially needed to be able to get a user, but also be able to pass in optional query params that would allow the results to be limited in quantity or by the date. I did this by checking the request for query params and then building up a new object to return. Does it work? Sure. The problem is this really isn't the route that would be optimal for scalability. (I mean, I assume this isn't what's going on when I check my profile on Strava.)

The struggle with making queries is making it easy to filter and/or get custom information returned. Sure, you can just make a user and always return everything, but you don't really want that either. Optimally you only want to return what the client actually needs so their device isn't doing all the heavy lifting. This is where GraphQL makes life easy.

Great, so what is it?!

GraphQL is basically a new query language. It lets you write a query such as the one below:

{
  query GET_USERS {
    users(name: "Ryan") { 
      id
      runs
      hikes
      totalExercises
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The query above, called "GET_USERS," is running a method/resolver (I'll get to that later) called "users()" that is accepting a name. If I pass in the name "Ryan" I will get back ALL of the users named Ryan, along with their user id, their runs, hikes, and a totalExercises. What if I wanted to know about all the runs for people named Jane? I could do:

{
  query JANE_RUNS {
    users(name: "Jane") { 
      id
      runs
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This would give me the users named Jane along with their id and all of their runs. It seems pretty great! GraphQL also has mutations you can use that work similarly taht allow you to write and edit changes to your database. So, how do those work? You can find out by reading my next post on Prisma! (Which...you'll have to come back for because it doesn't exist yet.)

The Goal

My goal is to create a short series of posts sharing what I have learned about GraphQL, Prisma, and Apollo. Partially to share what I have learned, but also because as a teacher I have learned that one of the best ways to truly learn something is to attempt to teach it to someone else. It exposes the things you really don't understand as you go along. If you happen across this post or the future posts and see something horribly wrong, feel free to chime in so we can all understand more together! If you are interested in how I started learning, I learned much of this though taking the Advanced React course offered by Wes Bos. I also dove in to the documentation a ton, but credit where credit is due. He has a lot of great content.

Top comments (0)