GraphQL APIs for everyone: An in-depth tutorial on how GraphQL works and why it's special

Understanding The GraphQL Query Language

The structure of the GraphQL query language is a declarative format that looks something like a cross between JSON and Python. The query language uses the curly bracket syntax to define a set of fields within an object (aka entity). But, unlike the way JSON uses commas to delimit a field, a GraphQL query uses line breaks or white spaces. Listing 1 below shows an example of a GraphQL query and the result of that query.

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"} ]
            }
          ]
    }
  }
}

Traditional description of one-to-many relationships in a relational database

Figure 1: A traditional way to describe one-to-many relationships in a relational database.

semantic web graphql

Figure 2: An object graph that describes the relationships between movies, actors, roles and directors.

semantic web graphql

Figure 3: A resolver is a function the provides the behavior for a given query.

Listing 5, below shows an example of syntax for executing the mutation, addPerson along with the results on the left side of the listing,

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"
    }
  }
}
semantic web graphql

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

GraphQL introspection generating API documentation

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

Query all Person objects in the system

Query Result
{
  __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"
                                                                                                                                                                                        }
                                                                                                                                                                                .
                                                                                                                                                                                .

Listing 12: Defining and executing a query based on a union

Server side type definitions (Comments in tripe quotes) Client side query in GraphQL
""
    "
    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 }
}
}
}
}

Listing 12: Defining and executing a query based on a union

Query Results
{
                                                                                                                                                                                  "data": {
                                                                                                                                                                                    "getPersonActor": [
                                                                                                                                                                                      {
                                                                                                                                                                                        "firstName": "David",
                                                                                                                                                                                        "lastName": "Bowie",
                                                                                                                                                                                        "roles": [
                                                                                                                                                                                          {
                                                                                                                                                                                            "character": "Thomas Jerome Newton",
                                                                                                                                                                                            "movie": {
                                                                                                                                                                                              "title": "The Man Who Fell to Earth"
                                                                                                                                                                                            }
                                                                                                                                                                                          }
                                                                                                                                                                                        ]
                                                                                                                                                                                      },
                                                                                                                                                                                      {
  "firstName": "Donnie",
                                                                                                                                                                                        "lastName": "Bowie"
                                                                                                                                                                                        "marriedTo: {
                                                                                                                                                                                          "firstName": "Emilia",
                                                                                                                                                                                          "lastName": "Bowie"
                                                                                                                                                                                        }
                                                                                                                                                                                      },
                                                                                                                                                                                      {
                                                                                                                                                                                        "firstName": "Emilia",
                                                                                                                                                                                        "lastName": "Bowie"
                                                                                                                                                                                        "marriedTo: {
                                                                                                                                                                                          "firstName": "Donnie",
                                                                                                                                                                                          "lastName": "Bowie"
                                                                                                                                                                                        }
                                                                                                                                                                                      }
                                                                                                                                                                                    ]
}
}
+

Esta página está disponible en español

Ver en español