What is GraphQL and how did it evolve from REST and other API technologies?

Interest in GraphQL has grown significantly since 2015, according to Google Trends.

Figure 1: Interest in GraphQL has grown significantly since 2015, according to Google Trends.

Paper based reporting was an early form of data exchange

Figure 2: Paper based reporting was an early form of data exchange

Sending a CSV file to a FTP server was an early method of data exchange between mainframe systems.

Figure 3: Sending a CSV file to a FTP server was an early method of data exchange between mainframe systems.

HTML hyperlinks make information in multiple media formats accessible in a nonlinear manner

Figure 4: HTML hyperlinks make information in multiple media formats accessible in a nonlinear manner

Representing a movie

Representing a movie in JSON Representing a movie in XML
{
"id": 4001,
"title": "The Man Who Fell to Earth",
"releaseDate": "1976-04-18",
"director":{"id": 102,
"firstName": "Nicholas",
"lastName": "Roeg", "dob": "1928-08-15"},
"actors" : [
{"id": 101, "firstName": "David", "lastName": "Bowie", "dob": "1947-01-08"},
{"id": 103, "firstName": "Rip", "lastName": "Torn", "dob": "1931-02-06"},
{"id": 104, "firstName": "Candy", "lastName": "Clark", "dob": "1947-06-20"},
{"id": 106, "firstName": "Buck", "lastName": "Henry", "dob": "1930-12-09"
}

< id>4001
                                                                                                                                                  < title>The Man Who Fell to Earth< /title>
                                                                                                                                                  < releaseDate>1976-04-18< /releaseDate>
                                                                                                                                                  < director>
                                                                                                                                                    < id>102< /id>
                                                                                                                                                    < firstName>Nicholas< /firstName>
                                                                                                                                                    < lastName>Roeg< /lastName>
                                                                                                                                                    < dob>1928-08-15< /dob>
                                                                                                                                                  < /director>
                                                                                                                                                  < actors>
                                                                                                                                                    < actor>
                                                                                                                                                      < id>101< /id>
                                                                                                                                                      < firstName>David< /firstName>
                                                                                                                                                      < lastName>Bowie< /lastName>
                                                                                                                                                      < dob>1947-01-08< /dob>
                                                                                                                                                    < /actor>
                                                                                                                                                    < actor>
                                                                                                                                                      < id>103< /id>
                                                                                                                                                      < firstName>Rip< /firstName>
                                                                                                                                                      < lastName>Torn< /lastName>
                                                                                                                                                      < dob>1931-02-06< /dob>
                                                                                                                                                    < /actor>
                                                                                                                                                    < actor>
                                                                                                                                                      < id>104< /id>
                                                                                                                                                      < firstName>Candy< /firstName>
                                                                                                                                                      < lastName>Clark< /lastName>
                                                                                                                                                      < dob>1947-06-20< /dob>
                                                                                                                                                    < /actor>
                                                                                                                                                    < actor>
                                                                                                                                                      < id>106< /id>
                                                                                                                                                      < firstName>Buck< /firstName>
                                                                                                                                                      < lastName>Henry< /lastName>
                                                                                                                                                      < dob>1930-12-09< /dob>
                                                                                                                                                    < /actor>
                                                                                                                                                  < /actors>
                                                                                                                                                < /movie>
An object graph structures data according to nodes and edges

Figure 5: An object graph structures data according to nodes and edges

GraphQL provides API access to entities and their relationships using continuous recursion

Figure 6: GraphQL provides API access to entities and their relationships using continuous recursion

GraphQL Query

GraphQL query Result
{
movie(id: "6fceee97-6b03-4758-a429-2d5b6746e24e"){
title
releaseDate
directors{
firstName
lastName
dob
}
actors{
firstName
lastName
roles{
character
}
}
}
}
{
"data": {
"movie": {
"title": "The Man Who Fell to Earth",
"releaseDate": "1976-04-18",
"directors": [
{ "firstName": "Nicholas",
"lastName": "Roeg",
"dob": "1928-08-15"
}
],
"actors": [
{ "firstName": "David",
"lastName": "Bowie",
"roles": [
{ "character": "Thomas Jerome Newton"
}
]
},
{
"firstName": "Rip",
"lastName": "Torn",
"roles": [
{
"character": "Nathan Bryce"
}
]
},
{
"firstName": "Candy",
"lastName": "Clark",
"roles": [
{ "character": "Mary-Lou"
}
]
},
{
"firstName": "Buck",
"lastName": "Henry",
"roles":
[
{
"character": "Oliver Farnsworth"
}
]
}
]
}
}
}

Query all Person objects in the system

Query Result
{
persons{
firstName
lastName
}
}
"data":
{ "persons": [
{
"firstName": "David",
"lastName": "Bowie"
},
{
"firstName": "Nicholas",
"lastName": "Roeg"
},
{
"firstName": "Rip",
"lastName": "Torn"
},
{
"firstName": "Candy",
"lastName": "Clark"
}
]
}
{
persons{
firstName
lastName
dob
}
}
{
"data": {
"persons": [
{
"firstName": "David",
"lastName": "Bowie",
"dob": "1947-01-08"
},
{
"firstName": "Nicholas",
"lastName": "Roeg",
"dob": "1928-08-15"
},
{
"firstName": "Rip",
"lastName": "Torn",
"dob": "1931-02-06"
},
{
"firstName": "Candy",
"lastName": "Clark",
"dob": "1947-06-20"
}
]
}
{
persons{
firstName
lastName
dob
knowsConnection {
firstName
lastName
}
}
}
{
"data": {
"persons": [
{
"firstName": "David",
"lastName": "Bowie",
"dob": "1947-01-08",
"knowsConnection": [
{
"firstName": "Nicholas",
"lastName": "Roeg"
}
]
},
{
"firstName": "Nicholas",
"lastName": "Roeg",
"dob": "1928-08-15",
"knowsConnection": [
{
"firstName": "David",
"lastName": "Bowie"
},
{
"firstName": "Rip",
"lastName": "Torn"
},
{
"firstName": "Candy",
"lastName": "Clark"
},
{
"firstName": "Buck",
"lastName": "Henry"
}
]
}
]
}
}

Mutation and Result

Mutation Result
mutation{
addPerson(person: {firstName: "Marlon",
lastName: "Brando",
dob: "1924-04-03"})
{
id
firstName
lastName
dob
}
}
{
"data": {
"addPerson": {
"id": "4ddac860-0769-42e3-9dd5-3901fbe33a11",
"firstName": "Marlon",
"lastName": "Brando",
"dob": "1924-04-03"
}
}
}
Once a client registers a subscription, it will receive messages from the API when a predefined event(s) occur.

Figure 7: Once a client registers a subscription, it will receive messages from the API when a predefined event(s) occur.

GraphQL inline fragment

{
movies{
title
actors{
... on Personable{
firstName
lastName
}
}
}
}
{
"data": {
"movies": [
{
"title": "The Man Who Fell to Earth",
"actors": [
{
"firstName": "David",
"lastName": "Bowie"
},
{
"firstName": "Rip",
"lastName": "Torn"
},
{
"firstName": "Candy",
"lastName": "Clark"
},
{
"firstName": "Buck",
"lastName": "Henry"
}
]
},
{
"title": "Performance",
"actors": [
{
"firstName": "Mick",
"lastName": "Jagger"
},
{
"firstName": "James",
"lastName": "Fox"
},
{
"firstName": "Anita",
"lastName": "Pallenberg"
},
{
"firstName": "John",
"lastName": "Bindon"
}
]
},
{
"title": "Dr. Strangelove",
"actors": [
{
"firstName": "Peter",
"lastName": "Sellers"
},
{
"firstName": "Slim",
"lastName": "Pickens"
}
]
},
{
"title": "Being There",
"actors": [
{
"firstName": "Peter",
"lastName": "Sellers"
}
]
}
]
}
}

Server side type definitions (Comments in tripe quotes)

Client side query in GraphQL

Query Results

"""
Create a search result object that returns fields either in the Person type or Actor type
"""
union SearchResultObject = Person | Actor
type Person implements Personable{
id: ID
firstName: String
lastName: String
dob: Date
marriedTo: Person
}
type Actor implements Personable{
id: ID
firstName: String
lastName: String
dob: Date roles: [Role]
}
type Role {
character: String!
movie: Movie
}
""" Define a query on the server side type definition that returns an array containing either Actor or Person types according to last name.
"""
type Query {
getPersonActor(lastName: String!): [PersonActorSearch]
}
{
getPersonActor(lastName: "Bowie") {
... on Person {
firstName
lastName
marriedTo {
firstName lastName
}
}
... on Actor {
firstName
lastName
roles{
character
movie {
title
}
}
}
}
}
GraphQL introspection make it easy to generate API documentation out of the box

Figure 8: GraphQL introspection make it easy to generate API documentation out of the box

__schema query

{
__schema {
types {
name }
}
}
#A partial display of introspection output
{
"data": {
"__schema": {
"types": [
{
"name": "Query"
},
{
"name": "CursorPaginationInput"
},
{
"name": "String"
},
{
"name": "Int"
},
{
"name": "Persons"
},
{
"name": "Person"
},
{
"name": "Personable"
},
{
"name": "ID"
},
{
"name": "Date"
},
{
"name": "PersonConnection"
}
.
.
.
+

Esta página está disponible en español

Ver en español