This content originally appeared on DEV Community and was authored by Mehdi Zed
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
}
}
}
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"
}
\]
}
\]
}
}
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);
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;
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;
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!
This content originally appeared on DEV Community and was authored by Mehdi Zed
Mehdi Zed | Sciencx (2021-02-26T14:33:06+00:00) Understand GraphQL in 5 minutes. Retrieved from https://www.scien.cx/2021/02/26/understand-graphql-in-5-minutes/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.