Blog / GraphQL

What is GraphQL

GraphQL is a query language for data graphs. Companies build and use GraphQL APIs to query data efficiently. Unlike Restful APIs, you can tell a GraphQL API what you exactly need, and the API returns the data you have requested. Moreover, you can batch multiple queries into one to fetch the data you need faster. In this article, I will introduce GraphQL and how it works.

Written byMatt
Published OnTue Jul 20 2021
Last UpdatedTue Jul 20 2021

Companies and individuals use online services to connect with friends, offer a digital service, and do their job, all of which results in storing petabytes of data every day. In addition, giant tech companies like Twitter, Facebook, Google, and Netflix serve millions of users daily through their mobile, desktop, and web applications. They realized that current solutions could not serve their ever-growing userbase efficiently, so they started thinking about new ways of making users’ data available.

GraphQL is one of the most recent innovations from Facebook, an efficient way to make users’ data available to mobile, desktop, and web applications via API. At its core, GraphQL is a language to query graphs of data. The language comes with an official specification. In addition, there are plenty of GraphQL server frameworks that allow developers to build GraphQL APIs that are compatible with the language specification. In this article, we will review GraphQL API in detail and how it can be of help in solving today’s data problems. Technical challenges and limitations of the existing solutions pushed Facebook to come with new ideas about how apps should fetch data and use it.

Table of Contents

Rest APIs are not efficient

Back in 2015, when Facebook announced GraphQL publicly, Rest APIs were the de-facto of the API world, and many companies, including Facebook, were using Restful APIs to make users’ data available to them. For example, a simple online shop had to send multiple HTTP requests to fetch the required data and display it.

As you may have noticed, the above works but has its’ own limitations, mainly:

In the context of a giant company like Facebook, it meant that millions of users were experiencing slowness and a lot of pressure on Facebook’s database. With the introduction of HTTP 2 and concepts like content negotiation, things got slightly better, but the underlying problem was still there.

Efficient data retrieval via GraphQL

Conceptually, GraphQL API models the data it works with as a graph. The nodes in the graph itself are connected, and the type of their relation (parent-child, one to one, one to many, many to many) is clearly defined. As a result, consumers of a GrphQL API (mobile, web, desktop, or 3rd-parties) can easily ask what they need and receive only what they asked. Moreover, consumers can take advantage of the Graph concept and request data from different parts of the graph all within one single request to the GraphQL API.

In our online shop example, the mobile app can send one HTTP request to the GraphQL server and fetch discounted products and the user profile. Moreover, the app can decide what portion of the product data set it needs.

In the following two paragraphs, we go through GraphQL’s core concepts and the powerful typing system that GraphQL offers today and explore the ways GraphQL can help improve the experience of our bookshop users.

Core GraphQL concepts

So far, we have talked about GraphQL and how fetching data via GraphQL is efficient. That said, GraphQL is more than a way to fetch data. In this section, we go through some of the core concepts in GraphQL and how you can use them in your next project.

GraphQL Query Language

GraphQL’s query capabilities allow you to quickly fetch the data you need, combine multiple sets of data and request what you need. The below example shows how we can fetch an author’s profile.

{
  authors(id: "2") {
    id
    name
    books {
      id
      title
    }
  }
}

GraphQL mutations

Apart from query capabilities, GraphQL offers a simple and elegant way to change data called mutations. Using GraphQL mutations, you can easily trigger add, update and delete actions on the server. The below example shows how an author can be added via GraphQL API.

mutation addAuthor {
  addAuthor(name: "haruki murakami", website: "harukimurakami.com") {
    id
    name
    website
  }
}

Aliases

Using aliases, you can rename the field names in response to match your requirements. The below example shows how the profile of two different authors is fetched using aliases.

{
  haruki: authors(website: "harukimurakami.com") {
    id
    name
    website
  }

  orwell: authors(website: "orwellfoundation.com") {
    id
    name
    website
  }
}

The response to this request will look like this:

{
  "data": {
    "haruki": {
      "id": "1",
      "name": "Haruki Murakami",
      "website": "harukimurakami.com"
    },
    "orwell": {
      "id": "2",
      "name": "George Orwell",
      "website": "orwellfoundation.com"
    }
  }
}

Fragments

Fragments allow you to reuse a portion of a query that otherwise you have to repeat multiple times. In our previous example, we have repeated the id, name, and name twice. We can leverage fragments to fix this problem. The result will be identical.

{
  haruki: authors(website: "harukimurakami.com") {
    ...authorProfile
  }

  orwell: authors(website: "orwellfoundation.com") {
    ...authorProfile
  }
}

fragment authorProfile on Author {
  id
  name
  website
}

Query Variables

GraphQL has the native support of variables. You can use variables to have dynamic queries. For example, let’s try to fetch an author’s profile using variables.

query authorProfile($id: ID!) {
  authors(id: $id) {
    id
    name
    email
  }
}

GraphQL types

In the previous section, we briefly talked about modeling your data as a graph and represent it using GraphQL. This section will cover core types in GraphQL and how they help you model your data as a graph.

Object types


Object types are one of the core components of any GraphQL API. Using an Object type, you can model your data. For example, for a typical online bookshop, we could define the following object types for authors and books:

type Author {
  id: ID!
  name: String!
  books: [Book!]!
}
type Book {
  id: ID!
  title: String!
  isbn: String!
  authors: [Author!]!
}

Scalar types

As we mentioned earlier, in GraphQL, everything has a type. Object types allow us to model our data by supporting fields. Therefore, each field in a GraphQL API must have a type, either an Object type or scalar type. GraphQL Scalar Types allows us to define the type of the low-level fields. Out of the box, GraphQL APIs support Int, Float, String, Boolean, and ID. Moreover, depending on the GraphQL framework of your choice, you should be able to introduce custom scalar types like Date when needed.

Nullable types

By default, all of the GraphQL types are nullable, which means that a field may or may not have the expected value. Let’s take the following Author object type as an example:

type Author {
  id: Int
  name: String
}

The above type definition translates to:

In reality, though, we know that authors all have a unique ID and a name, so we can add the ”!” sign at the end of each type to make them non-nullable.

type Author {
  id: Int!
  name: String!
}

Lists

GraphQL supports lists (arrays). Each list will have a type, either object type or scalar type. For example, the “books” field in the below example is a list of non-nullable books.

type Author {
  id: ID!
  name: String!
  books: [Book!]!
}

Enumeration types

Using Enumeration types, you can define a type and possible values for that type. For example, the status of a book in our bookshop example can be either AVAILABLE, UPCOMING, or SOLD_OUT. The below code shows how we can define the “BookStatus” enumeration type and use it in our Book type.

enum BookStatus {
  AVAILABLE
  UPCOMING
  SOLD_OUT
}

type Book {
  id: ID!
  title: String!
  status: BookStatus!
}

Union Types

Using Union Types in GraphQL, a field can have more than one type. Union types are mostly for edge cases and not something you will need to use daily. In our bookshop example, let’s say we need to return search results, either an author or a book. We could do it using union types.

type Book {
  id: ID!
  title: String!
}

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

union SearchResult = Book | Author

Field arguments

Field arguments are one of GraphQL unique features. Using this feature, you can pass extra information to a field (at any level) to return value. In our bookshop example, we could tweak the “title” field of Book to accept a language. When provided, we could use this value to return the book title in the provided language.

enum Language {
  ENGLISH
  SPANISH
  RUSSIAN
}

type Book {
  id: ID!
  title(lang: Language!): String!
  status: BookStatus!
}

Input Types

Input types are a companion for Field arguments, and you can use Input types to pass a group of values as one argument. For our bookshop search, we could define a SearchQuery input type to accept multiple values under one argument:

input SearchQuery {
  keywords: String!
  pageIndex: Int
  pageSize: Int
}

Interfaces

Interfaces allow you to define a set of object types with common fields. Our bookshop example could leverage GraphQL Interfaces to support paper books, ebooks, and audiobooks.

interface Book {
  id: ID!
  title: String!
}

type PaperBook implements Book {
  # shared between all kinds of books
  id: ID!
  title: String!

  # unique to Paper Books
  isbn: String!
}

type EBook implements Book {
  # shared between all kinds of books
  id: ID!
  title: String!

  # unique to ebooks
  ePubFile: String!
  pdfFile: String!
}

type AudioBook implements Book {
  # shared between all kinds of books
  id: ID!
  title: String!

  # unique to audiobooks
  steamLink: String!
}

type Author {
  id: ID!
  name: String!

  # including an interface (Book)
  books: [Book!]!
}

Top 5 benefits of GraphQL APIs

Although efficient data fetching is the most significant advantage of using GraphQL, some other great benefits, in this section, we cover some of GraphQL API advantages:

Top 3 GraphQL challenges

GraphQL’s novel approach to data fetching made it possible to solve many problems and offer great benefits. That said, this novel approach also introduced a new set of challenges that are worth knowing upfront.

Testing GraphQL APIs

Almost all GraphQL APIs are available via HTTP protocol and return data in JSON format, so you should leverage your existing tools and techniques to test GraphQL APIs. If you haven’t read it already, we highly recommend having a read of the best API testing tools we wrote a while back. It compares some of the best API testing tools in the market, and most of them support GraphQL API testing.

Testfully supports testing GraphQL APIs, so you can easily leverage our platform for this purpose.

If your API testing tool does not support GraphQL but does support Restful APIs, you should be able to use it for testing a GraphQL API. When you want to query a GraphQL API, think of the API as an endpoint in a Restful API that only accepts HTTP POST requests. You can send a POST request and pass the following JSON object as a request payload:

We talked about how to test GraphQL APIs. In this section, we go through what you need to test.

Top 10 GraphQL best practices

At Testfully, we have been building and supporting GraphQL APIs for some time, and throughout our journey, we have learned a couple of things that we would like to share with you as GraphQL best practices.

Top 5 free GraphQL clients/IDEs

As we talked about earlier, due to their strongly typed nature, GraphQL APIs are all self-documented. Using a GraphQL client allows you to explore available types to query and mutate quickly.

GraphQL APIs to play with

To better understand GraphQL APIs and how they tackle problems, we have put together four free GraphQL APIs you can play with to understand GraphQL better.

Useful resources

We have put together a list of resources to help you get on board with GraphQL API. Whether you’re a user of GraphQL or planning to build a GraphQL API, there should be something in this list for you.

FAQ

What’s the difference between GraphQL unions and GraphQL interfaces?

Both GraphQL union and interface types allow a field to have more than one type. However, unioned types do not need to have fields in common, while types that implement an interface must have the common fields defined by the interface.

is GraphQL a database?

No, GraphQL is a language to query data. The data itself may be stored in a database, disk, or fetched via other services. GraphQL offers a way to query data that is not coupled with the way the data is stored.

What is the difference between GraphQL and SQL?

Both GraphQL and SQL are query languages. While SQL is a query language for querying relational databases, GraphQL is a query language for data graphs.

Concusion

In this article, we went through the problems that GraphQL attempts to solve, what benefits we get and what new challenges GraphQL introduces. First, it’s essential to acknowledge that GraphQL is not a silver bullet by any means and like any other technology, GraphQL comes with limitations.

Testfully is a bootstrapped startup from Sydney, Australia.
We're funded by our supportive & amazing customers.

The word `testfully` is a registered trademark of Testfully Pty Ltd.