The Magic of GraphQL

The Magic of GraphQL

If you have ever built a web app, you most probably know what a REST API is. A REST API consists of a URL endpoint that you can hit with the various HTTP methods from the client (GET, POST, PUT, UPDATE) and make the server perform various actions. For example, to get information from your server, say about MCU movies, you could hit an endpoint "www.yourapp.com/mcumovies" with a GET request, and you would get a list of JSON objects consisting of all MCU movies, like so:

[
  {
    "name": "Iron Man",
    "year": "2008",
    "actor": "Robert Downey Jr.",
    "director": "Jon Favreau"
  },
  {
    "name": "Thor",
    "year": "2011",
    "actor": "Chris Hemsworth",
    "director": "Kenneth Branagh"
  },

  ... // More movies

]    

You would then use this data at the frontend (client side). Maybe you simply wish to display this data or maybe you wish to further use it somewhere. Let us assume you want to make an app that displays all MCU movies and the director name and age along with them. You already have an endpoint that gives you the list of all movies. Let there be another endpoint that gives you details of all MCU directors. For our purpose, we need to get the directors' ages. So, for each director, we need to hit another endpoint "www.yourapp.com/mcudirectors" with a GET request and the relevant parameters so that the server returns us the required director's details. For example, a GET request to "www.yourapp.com/mcudirectors?name=Jon%20Favreau" will give you:

{
  "name": "Jon Favreau",
  "age": "50",
  "nationality": "American",
  "movies": [
              {
                "name": "Iron Man",
                "name": "Iron Man 2",
                "name": "Iron Man 3",
                "name": "Spiderman: Homecoming",
                "name": "Avengers: Endgame",
                "name": "Spiderman: Far From Home"
              }
            ]
}

So, now what we have to do is:

  1. Get all MCU movies using the "/mcumovies" endpoint
  2. Get all details of the relevant director from the "/mcudirectors" endpoint, extract out the age from it, and display the info in the UI.

So, this works. It does, and if you're happy with making multiple HTTP calls and getting additional data unnecessarily, you can stop reading and go back to the stone age of REST APIs. But if you want to scale your application, make it fast and sleek, welcome to the world of GraphQL.

I've read about a page's worth of your unnecessary blabber. When are we going to talk about GraphQL?

Yeah, we're getting to it.

So, GraphQL stands for Graph Query Language. You've probably heard of SQL, right? SQL is a Query Language for your database. Similarly, GraphQL is a query language for your APIs, which was an absolutely ridiculous concept up till now. GraphQL has been developed by Facebook, and is a way to complete remove the above discussed redundancy, and make your life really simple.

With GraphQL, you define relations in your data at the server. These relations can be represented by edges, and so, your data is in the form of graph (and hence the name). I'll not go into how we define these relations in the backend in this article, for the sake of compactness, but we will discuss how we query our GraphQL backend service.

Queries:

Unlike REST APIs, a GraphQL backend service exposes data over a single endpoint. This means no worrying about GET parameters, different URLs etc. All we have to do is define a query like so:

query GetMovies {
  movies {
    name
    year
    actor
    director
  }
}            

... and send this query to the server. Here, GetMovies is the name of the query, for future use. "movies" is the keyword we have programmed our backend service to respond to, and "name, year, actor, director" are the fields we want to be returned.

So, why do we need to define fields the server has to return? Well that's the magic wand given to us by GraphQl. You see, we can leave out fields from our query and the server will simply not send us that redundant data.

query GetMovies_NameAndYear {
  movies {
    name
    year
  }
}

This will return data like so:

{
  "data": {
    "movies": [
      {
        "name": "Iron Man",
        "year": "2008"
      },
      {
        "name": "Thor",
        "year": "2011"
      },
      
      ... // More movies

    ]
  }
}

So, with GraphQL, what you ask for is what you get. There is no redundant data returned to us, and data returned is in the same structure as the query.

Woah this is already really cool, man. Is there anything else GraphQL can do?

Well we haven't explored that "Graph" part of "GraphQL" yet. As mentioned earlier, GraphQL allows you to define relations among your data. For example, here, a movie has a one-to-one relationship with a director, and a director can have many movies under him. Everything is exposed under a single endpoint, and everything can be queried seamlessly. Remember the two REST endpoints we had to hit earlier? Lets see how we can get data from our new and shiny GraphQL endpoint:

query GetMoviesAndDirectors {
  movies {
    name
    year
    director {
      name
      age
      movies {
        name
      }
    }
  }
}

(Note: Previously, the query GetMovies had no fields returned for field "director" because the server was programmed to return a string, now we have an object being returned and so, we ask for fields in that object)

I have included movies under director just to give you the flavour of awesomeness of GraphQL. We do not need it for our MCU application, we just need the name and age of the director.

Parameters:

Nice! But what if we need to query for a specific movie? What is the equivalent of GET parameters here?

You can specify parameters in GraphQL queries too. If you want to query for a specific movie, you can send this query:

query GetMovie {
  movie(name: "Iron Man") {
     year
     actor
     director {
        name
     }
  }
}

Notice the "name" parameter we have given to our "movie" query. Note the query keyword "movie" is different than the earlier keyword "movies" to get all movies. We need to program our backend service to check the supplied parameter on receiving the "movie" query and then returning the required data.

Mutations:

The second type of commands you can send to to your backend are called "mutations". Mutations are required when to need to send data to be stored or updated at the backend. Suppose we want to add a new movie that just came out to our backend API. We can create a mutation like so:

mutation AddMovie(name: "Doctor Strange 2", year: "2021", ... /* Other parameters */) {
  added
}

Depending on our backend implementation, the parameters will be taken by the server, and a new movie object will be added to the database.

But what is the "added" field returned by the mutation? Every mutation in GraphQL has to return something. Most of the times, when we add a new object to the database, a unique ID is generated, and that is what we wish to be returned from the server. Here, I've simple asked a boolean field "added" to be returned, which informs us whether the addition of a new object to the database was successful or not.

So, should I shift my existing REST apps to GraphQL? Man, that is a LOT of effort.

Nope. It all depends on your application. Maybe your application requires all of the data every time. Then, it doesn't really make sense to avoid redundancy, because there is none. But most of the times, apps that currently use REST would be better off with GraphQL. Its effort and time vs efficiency in the balance, and you need to decide for your specific application requirements.

That's all folks! I hope I helped you understand GraphQL a little. For moving forward, and making your first GraphQL app from scratch, I would recommend this amazing playlist by "The Net Ninja" on YouTube:

https://www.youtube.com/playlist?list=PL4cUxeGkcC9iK6Qhn-QLcXCXPQUov1U7f

This playlist covers everything from frontend to backend. In case you do not understand some languages or frameworks he uses (Node, React etc), you can see other playlists on these topics on the same channel. All the best!


I would add the specific GET queries, and show results with something like cURL. Great work!  

To view or add a comment, sign in

More articles by Shashwat Jolly

  • GSoC 2020 with KDE and EteSync

    I am elated to be selected for GSoC with KDE! Through the program, I aim to dive deeper into open-source and utilize…

    18 Comments
  • Why the Surface Matters a Lot

    Microsoft recently revealed its new Surface Lineup for the upcoming year. The new devices are the Surface Pro 7…

    4 Comments
  • Node, Express, NPM: What do they mean?

    You may have heard of all these terms thrown about: "Learn web development with node", "Make an express server" etc…

  • An introduction to JavaScript for beginners, by a beginner

    I started working as a Software Development Intern at Microsoft, India just a few days back. I have a web-based project…

    6 Comments

Others also viewed

Explore content categories