GraphQL 101: Query Language Part 1

In Intro to GraphQL, we learned that GraphQL consists of a query language and a server runtime. Queries, mutations, and subscriptions are defined within the query language which contains the following parts.

  • Operations - the document which contains the types of operations: query, mutation, and subscription along with any fragments.
  • Document - GraphQL has two types of documents: execution (query) documents and schema documents (which will be discussed in a future post)
  • Selection sets - with an execution document a set of fields that make up the content contained within curly braces.
  • Fields - and object-specific attribute that can be requested and returns a value.
  • Arguments - are named values that are provided to its field function and change how it behaves.
  • Variables - are declared after the operation name, for example,
    query UserName($id: Int!). The $ signals that this is a variable and ! indicates that the value is nonnullable.
  • Field aliases - changes the name of a field that was declared on the server in the retuned response.
  • Fragments - there are three types of fragments: named fragments allow us to reuse fields, type conditions allow us to conditionally select fields and inline fragments that don't have a name defined inside the selection set.
  • Directives - there are four directives defined in the spec: @skip, @include, @specifiedBy and @deprecated. All directives begin with the @ symbol and change how a section of the document is validated or executed by the server. Custom directives are allowed and frequently used.
  • Mutations - Technically “mutation” is an operation type, but top-level mutation fields are often called “mutations.” Mutations alter data.
  • Subscriptions - These are long-lived requests that allow the server to send the client events as they happen.
    FUN FACT: Facebook added subscriptions to GraphQL to enable updating "Like" clicks.

Operations

The GraphQL Specification sets the rules for how a client or application communicates with the server. The purpose of an application's communication with the server in its simplest form is to request data and to make changes to data. In REST, communication with the server/API is expressed as HTTP verbs: GET, POST, PUT, PATCH, and DELETE. These are requests to the server for some action related to a data resource. And in the lingo of servers that provide data storage from a database, communication is expressed as CRUD or Create, Read, Update and Delete. When people talk about CRUD, they usually refer to CRUD operations. GraphQL uses the term Operations as a category for three types of communication with the server for data operations: query, mutation, and subscription.

Examples

A query can be simple like the one we started with from Intro to GraphQL from Github. Let's at some operations like query and mutation with additional fields and a variable, also using the Github v4 API.

Query

#This will return the login ID for whoever runs this query.

query { 
  viewer { 
    login
  }
}
#A similar query with a single variable

query($number_of_repos:Int!) {
  viewer {
    name
     repositories(last: $number_of_repos) {
       nodes {
         name
       }
     }
   }
}
variables: 
{
   "number_of_repos": 3
}

A bit more complex query of the Github GraphQL API.

#This query looks up the octocat/Hello-World repository, 
finds the 20 most recent closed issues, and returns each
issue's title, URL, and first 5 labels.

query {
  repository(owner:"octocat", name:"Hello-World") {
    issues(last:20, states:CLOSED) {
      edges {
        node {
          title
          url
          labels(first:5) {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    }
  }
}

Mutation

#This query looks up an issue ID and the mutation adds
the emoji to the issue.

query FindIssueID {
  repository(owner:"octocat", name:"Hello-World") {
    issue(number:349) {
      id
    }
  }
}

mutation AddReactionToIssue {
  addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}
#This is the same query and mutation as above but
this time we make use of variables.

mutation($myVar:AddReactionInput!) {
  addReaction(input:$myVar) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}
variables {
  "myVar": {
    "subjectId":"MDU6SXNzdWUyMTc5NTQ0OTc=",
    "content":"HOORAY"
  }
}

The Query Language Part 2

In part 2, we'll continue expanding on some examples to include fragments, directives, and Subscriptions. We'll look at some live-running examples too in a later post.

Feel free to share feedback or ask questions. Just @ me on Twitter.