DEV Community

Cover image for Understand GraphQL in 5 minutes
Mehdi Zed
Mehdi Zed

Posted on • Originally published at jesuisundev.com

Understand GraphQL in 5 minutes

When GraphQL arrived on the Internet, it spread like an epidemic. GraphQL has completely changed the way things are done and continues its progression everywhere. If you have five minutes in front of you, I'll explain everything you need to know.

Once upon a time

By 2012, the adoption of mobile phones reached monstrous figures worldwide. It's such an invasion that companies that didn't adapt their products were at risk. At that point, Facebook was at risk.

Facebook was primarily a web company. As a result, they made their IOS app like a website, using web-view. Very quickly, they realize that web-view was shit (at that time). So they decided to redo it entirely in native, for a better customer experience. Immediately they hit another wall .

The existing architecture didn't work. Mainly because the endpoints of their existing REST api don't allow flexibility on the data. Multiple round trips to different endpoints were required for nested data, causing slowness and inconsistencies. Part of the payload was not required for most queries, causing unnecessary data transfers. And most importantly, it was tedious for Facebook to handle so many HTTP calls.

In this infernal context, in February 2012, Lee Byron, Dan Schafer and Nick Schrock reserved some workstations in a corner of Facebook.

Very quickly a first prototype of GraphQL, then called SuperGraph, was produced by our three devs. In August 2012, GraphQL was shipped in production with the new native Facebook app. In 2015, the first public version arrives on the internet. GraphQL is still present today when you scroll your Facebook wall. But how did they solve a problem that affected not only Facebook, but the whole industry?

What is GraphQL ?

GraphQL is a data query language for APIs. QL, as in SQL, stands for Query Language. GraphQL allows to manipulate data in a simple, flexible and very precise way. GraphQL is not a programming language nor a framework. GraphQL is a specification to implement your API. Concretely it looks like this.

Request

{
    pokemons {
        name,
        abilities {
          name,
          damage,
          accuracy,
          mana,
          type
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Response

{
    "data": {
        "pokemons": \[
            {
                "name": "pikachu",
                "abilities": \[
                    {
                        "name": "Thunder punch",
                        "damage": 75,
                        "accuracy": 70,
                        "mana": 15,
                        "type": "physical"
                    },
                    {
                        "name": "Thunderbolt",
                        "damage": 90,
                        "accuracy": 80,
                        "mana": 15,
                        "type": "electric"
                    }
                \]
            },
            {
                "name": "mewtwo",
                "abilities": \[
                     {
                        "name": "Earthquake",
                        "damage": 130,
                        "accuracy": 100,
                        "mana": 20,
                        "type": "ground"
                    },
                    {
                        "name": "Brutal swing",
                        "damage": 180,
                        "accuracy": 90,
                        "mana": 25,
                        "type": "physical"
                    }
                \]
            }
        \]
    }
}
Enter fullscreen mode Exit fullscreen mode

That's how you ask for and receive data using GraphQL. Okay, at the moment, it's not clear. First of all, where does this thing fit into your architecture?

The dude smiling it's you. And to make the payload I showed you earlier with the Pokemons and their skills, you're in trouble. You're struggling because the REST API you're using is not made for your needs. You end up making one call per Pokemon, then one call per skill for each Pokemon.

Each time the logic in your application makes a request to the database and sends you a payload. And so, despite your apparent smile, you feel like shooting yourself. That's where GraphQL comes in.

With GraphQL, no more problems. You make a single POST and you ask exactly what you want via a GraphQL request. Then, the server manages everything and you get your full payload.

With REST, you get objects defined by endpoints. With GraphQL, you don't adapt to a object defined by the backend, you dynamically define the object you're going to receive on the client side. And that changes everything.

OK, that's all very well, but how does it work in concrete terms? How does GraphQL access your database and make queries? To really understand GraphQL, you have to get your hands on it.

Show me the code

I'm going to make you a Javascript implementation (NodeJS).Be aware that all the following is applicable in any language. The GraphQL logic remains the same everywhere since it is above all a specification.

To start working on GraphQL go to the official site and their implementation list in all languages of the world. To make it simple with NodeJS we need the express-graphql and graphql modules. Let's start by mounting the base server.

index.js

const path = require("path");
const express = require("express");
const graphqlHTTP = require("express-graphql");
const graphql = require("graphql");

const { query } = require(path.resolve("schema/query"));
const graphQLSchema = new graphql.GraphQLSchema({ query });

const app = express();

app.use(
  "/graphql",
  graphqlHTTP({
    schema: graphQLSchema,
    graphiql: true
  })
);

app.listen(8080);
Enter fullscreen mode Exit fullscreen mode

First of all, we call our dependencies. Then line 6 we look for our root query which we pass to the main schema on line 7. We launch our express server, we expose the /graphql route via an express middleware and finally we listen on port 8080. Let's see what happens inside the schema now.

schema/query.js

const path = require("path");
const { GraphQLObjectType, GraphQLList } = require("graphql");
const { pokemonsType } = require(path.resolve("schema/types"));

const RootQuery = new GraphQLObjectType({
  name: "RootQueryType",
  type: "Query",
  fields: {
    pokemons: {
      type: new GraphQLList(pokemonsType),
      resolve() {
        const data = require(path.resolve("data/pokemons.json"));

        return data;
      }
    }
  }
});

exports.query = RootQuery;
Enter fullscreen mode Exit fullscreen mode

The schema is central in GraphQL. It will dictate the communication between your client and your server. I*t specifies the queries your clients can make, the types of data that can be retrieved and the relationships between these types.* Everything is defined in this schema. Starting with the root query.

The root query allows GraphQL to know what type of data can be retrieved. And here, in my root query, I specify that I have a field pokemon line 9 which is a list of type pokemon line 10.

Then we have a resolver on line 11. It's the resolvers that do the job of fetching your data from your database. A resolver is assigned to each of your fields. And the resolver for my pokemon field is a pokemon object list. My resolver here returns the data via a JSON file that corresponds to an array of pokemons.

I return a JSON for the data for simplicity and brevity. But in real life this is where you are supposed to call your database, make queries, and return the data. Now let's see what the types look like.

schema/types.js

const path = require("path");
const graphql = require("graphql");
const { GraphQLObjectType, GraphQLString, GraphQLList } = graphql;

const abilitiesType = new GraphQLObjectType({
  name: "ability",
  fields: {
    name: {
      type: GraphQLString,
      resolve: parent => parent.name
    },
    damage: {
      type: GraphQLString,
      resolve: parent => parent.damage
    },
    accuracy: {
      type: GraphQLString,
      resolve: parent => parent.accuracy
    },
    mana: {
      type: GraphQLString,
      resolve: parent => parent.mana
    },
    type: {
      type: GraphQLString,
      resolve: parent => parent.type
    }
  }
});

const pokemonsType = new GraphQLObjectType({
  name: "pokemons",
  fields: {
    name: {
      type: GraphQLString,
      resolve: parent => parent.name
    },
    abilities: {
      type: new GraphQLList(abilitiesType),
      resolve(parent) {
        const abilities = require(path.resolve("data/abilities.json"));

        return abilities.filter(ability =>
          ability.linkedTo.includes(parent.name)
        );
      }
    }
  }
});

exports.pokemonsType = pokemonsType;
Enter fullscreen mode Exit fullscreen mode

The principle remains the same. We create GraphQL object types that represent our data structure. We specify fields and for each field, we assign a resolver that will look for the right data. It's interesting to see here that I use the context of the parent to filter which abilities to return for each pokémon line 44.

If you want to see a working version of this implementation, I made a little public sandbox where you can play with it. You can see all the files, including the JSON files, and change whatever you want!

Instead of JSON data you could implement the same thing by doing fech on PokéAPI. That would allow you to practice GraphQL as well.

Epilogue

That's it, I can't go any further in the presentation. I'm already over the five minutes of time you gave me. There's a lot more to be said about this technology. The mutations, the cache, the variables and the contexts. I'll stick to the basics. If you want to know more and have some time to spare, I recommend this very complete article!

Top comments (4)

Collapse
 
billraymond profile image
Bill Raymond

That was the best layperson explanation I’ve ever read on GraphQL. Thank you!

Collapse
 
imprimph profile image
Jaswanth

On Point and very clear :)

Collapse
 
devparkk profile image
Dev Prakash

Incredible tutorial

Collapse
 
harshvats2000 profile image
HARSH VATS

Cool and to the point explanation. Feels like a story and not a tutorial or anything:)