GraphQL deep dive for frontend developers

GraphQL is a language for querying data. It is widely used as an alternative to REST. In this post, I try to explain the most important concepts of GraphQL and how to use them.

What is GraphQL?

GraphQL is a language used to query data between two endpoints (client to server, server to server and etc.).

Unlike REST, in which you have several endpoints, in GraphQL you have only one endpoint. In GraphQL queries you define which object(s) do you need and which properties of the object you need.

why GraphQL?

GraphQL provides a much flexible way to query data. In GraphQL you only fetch data you need, not all of the data which an endpoint provides.

GraphQL has a powerfull type system which makes it possible to provide toolings like autocomplete and error checking and therefore a much better developer experience.

GraphQL makes it easy to query object and its relationships in one request (user and her posts in a blog for example).

In REST different versions of the API should be maintained, if a breaking change in the api is introduced. In GraphQL you can depricate parts of query without having to depricate the entire query.

GraphQL terms:

Some of common terminologies in GraphQL are:

Field:

fields are properties we want to query from an object. In the example below name and email are fields of user object.

{
  user {
    name
    email
  }
}

Argument:

GraphQL queries also accept arguments. In the following example we query name and email of a user with Id 32.

{
  user(id: "32") {
    name
    email
  }
}

Alias:

Alias makes it possible to query same object with different parameters. In the following example we query name and email of a user object, give the user with Id of 32 alias of user1 and the user with Id of 55 an alias user2.

{
  user1: user(Id: 32) {
    name
    email
  }
  user2: user(Id: 55) {
    name
    email
  }
}

Querying both users without alias wouldn’t have been possible.

Fragment:

Fragment is a way to to reuse repeating parts of query. For example we can store store name and email fields of the above query in a Fragment

{
  userOne: user(Id: 35) {
    ...userFields
  }
  userTwo: user(Id: 55) {
    ...userFields
  }
}

fragment userFields on User {
  name
  email
}

Variables:

As you saw in previouse examples we have hardcoded parameters like UserId, variables lets you add dynamic values in query.

query UserAndComments($userID: UserID) {
  user(userID: $userID) {
    name
    comment {
      title
      content
      date
    }
  }
}

Variables can have default values. Default values are used when query is used without passing a parameter.

query UserAndComments($userID: UserID = 12) {
  user(userID: $userID) {
    name
    comment {
      title
      content
      date
    }
  }
}

Directives:

Directives allows you to modify queries dynamically. For example @include(if: Boolean) is similiar to

if(true) {
/* do this */
} 

in Javascript. It conditionally shows fields

There are two directives in GraphQL sepc.

@include(if: Boolean):

As already discussed includes fields only if the condition is true.

@skip(if: Boolean)

It skips the field if the condition is true.

In the example below we include comments and its fields in query only if the variable $includingComments is true.

query User($id: Id, $includingComments: Boolean!) {
  user(id: $id) {
    name
    comments @include(if: $includingComments) {
      title
      content
      date
    }
  }
}

GraphQL mutation

We have been writing queries sofar (Asking for data). The following two snippets are identical.

UserNameAndEmail{
  user {
    name
    email
  }
}
query UserNameAndEmail{
  user {
    name
    email
  }
}

GraphQL supports creating, updating and deleting queries through mutations. we can replace query with mutation to mutate (create, update and delete) data. The following query deletes a user with ID 32.

mutation DeleteUser{
  user(id: "32") {
  }
}

GraphQL Types

Types in GraphQL makes it possible to define and validate what types(Number, string and etc.) of arguments a query accept and what types of queries does a query returns. “GraphQL schema language” is used to define types for GraphQL.

To define a type, you use the type type keyword. In the example below we define a user type, with an Id of type Integer and name of type string.

type User {
  id: ID
  name: String
}

Scalar types

Scalar types are Non compound and single values. Integers, strings and booleans are scalars values but arrays and objects are not. GraphQL schema language supports the following scalar types.

Int:

a signed 32 bit number (integer).

Float:

a number with decimal points.

String:

UTF‐8 text (one or more characters).

Boolean:

true or false.

ID:

ID is a unique identifier for objects, it is similiar to string, but was defined as its own type to denote that it is not meant to be human readable

Object types

Fields can be of objects as well. In the following example we define Post as type of blogPost.

type User {
  id: ID
  name: String
  blogPost: Post
}

Enums

Enums are a list of allowed values. For example the user marital status can be an enum with single, married, other values.

enum MaritalStatus {
  Married
  Single
  Other
}

Lists

Lists are a list of values (like arrays in javascript). In the following example we define blog posts as array of posts.

appearsIn: 
type User {
  id: ID
  name: String
  blogPosts: [Post]!
}

non-nullable values

non-nullable fields are are suffixed with an exclamation mark. non-nullable are guaranteed to return a value. In the following example we define id and name as non-nullable.

type User {
  id: ID!
  name: String!
}

GraphQL introspection

You may have asked yourself, how do I know which fields are available in a query, the answer is introspection. Introspection helps you with querying what fields are available to query and which type do they have.

Practicing GraphQL

If you do not already have a GraphQL server of your own, you can use the following free and public APIs to play with GraphQL.

Implementing GraphQL in your application

GraphQL is just a specification, you can implement GraphQL in any language and without any library or framework.

But there are lots of libraries available for major javascript frameworks/libraries on the client side and implementations for major programming languages on the server.

For a list of all client and server implementations visit GraphQL code page. As a frontend developer I recommend you skimming through Apollo tutorials.