A Beginner’s Guide to GraphQL

You are currently viewing A Beginner’s Guide to GraphQL

In 2000, Roy Fielding invented REST and changed the Web APIs landscape forever. Many companies developed their applications using REST APIs and it became very popular because of its simplicity and improved performance. These days APIs have become a lot more complex than before. APIs now need to send a large amount of structured and unstructured data from a variety of data sources without compromising on performance and efficiency. This is why a new tech was needed therefore the developers at Facebook invented a new but very cool query language called GraphQL. Initially, it was only used by Facebook developers but later on Facebook made it publically available to the general public. Many people immediately started to see the benefits of using GraphQL and have switched their APIs over to GraphQL. In this tutorial, I will give you an overview of GraphQL and its architecture. You will also learn how GraphQL is different than the REST APIs and what problems it solves.

What is GraphQL?

GraphQL is a query language as well as a server-side runtime to build efficient and high-performance Web APIs. It was developed by Facebook in 2012 and then it was made public in 2015. It is now overseen by the GraphQL Foundation. GraphQL specification is open source therefore we now have dozens of implementations of GraphQL in every major programming language. GraphQL is designed to make APIs fast, flexible, and developer-friendly. Unlike REST, GraphQL APIs can accept all incoming requests at a single endpoint, and data can be pulled and served from multiple data.

In GraphQL, a client has full control over the data that API should return from the server. The client typically sends a POST request in JSON format to get exactly the data it needs.

An Example GraphQL API Request

query {
    team {
        id
        name
    }
}

An Example GraphQL API Response

{
  "data": {
    "team": [
      {
        "id": "1",
        "name": "Liverpool"
      },
      {
        "id": "1",
        "name": "Arsenal"
      },
      {
        "id": "1",
        "name": "Chelsea"
      }
    ]
  }
}

The server handles incoming queries, parses those queries, validates the queries using the defined schema, and finally used resolvers to fetch and aggregate data which is then returned in the response usually in JSON format.

GraphQL Execution Engine
GraphQL Execution Engine

GraphQL vs. REST

Both GraphQL and REST are used to build Web APIs but there are a lot of differences between the two technologies.

  1. The number of endpoints – In REST, we normally use multiple API endpoints to obtain the data we need whereas GraphQL exposes just one endpoint and the client can get all required information using that endpoint. It is also much easier to maintain and scale GraphQL APIs as there is only one endpoint involved.
  2. Allowed HTTP Verbs – In REST, we are allowed to use any HTTP verb, e.g. GET, POST, PUT, etc. whereas GraphQL supports only POST requests.
  3. Available Protocol – REST only works with HTTP, while GraphQL does not need HTTP.
  4. Request/Response Definition – In REST, the server-side API code defines the request and response format whereas GraphQL gives complete control to the client to define the request and response as per requirement.
  5. No versioning problems – In REST, we normally implement different API versions for supporting clients with different requirements. GraphQL doesn’t need versioning because every client can request exactly what data it needs.
  6. Fewer round trips to the server – GraphQL requires fewer round trips to the server because the client can request all the data in a single request. In REST, we usually require multiple API calls to load data from the server.
  7. No over-fetching or under-fetching – in REST, we sometimes receive unnecessary data from APIs whereas GraphQL let the client specify what information it needs so the client will never get too little or too much data from the server.
  8. Reduced bandwidth – Due to fewer requests to the server and not over-fetching any unnecessary data, the GraphQL APIs reduce the bandwidth and resource usage significantly.
  9. Learning curve – REST APIs are very simple to learn and implement and there are hundreds of books and training courses available whereas GraphQL presents a steep learning curve for developers.
READ ALSO:  Consuming GraphQL APIs in ASP.NET Core

What Problem GraphQL Solves

There are many downsides of REST APIs but a few of the major problems GraphQL solves are the following:

  • Over-fetching – REST API sends you more data than you need
  • Under-fetching – REST API sends you less data than you need
  • Multiple requests or round trips – You require multiple requests and round trips to the server to get the data you need

Let’s say you have a REST based API GET /countries that returns the list of countries as shown in the following JSON response but you are only interested in the country name and capital information. This is a clear example of over-fetching data. The API payload not only contains more data than what you need but all this data will also consume more network bandwidth.

{
  "countries": [
    {
      "name": "New Zealand",
      "capital": "Wellington",
      "currency": "NZD",
      "continent": {
        "name": "Oceania"
      }
    },
    {
      "name": "Norway",
      "capital": "Oslo",
      "currency": "NOK",
      "continent": {
        "name": "Europe"
      }
    },
    {
      "name": "Italy",
      "capital": "Rome",
      "currency": "EUR",
      "continent": {
        "name": "Europe"
      }
    }
  ]
}

Let’s say you have a REST based API GET /countries that returns the list of countries as shown in the following JSON response. What if you also need continent details with every country. The API payload is only returning continent code and this is a clear example of under-fetching.

{
  "countries": [
    {
      "name": "New Zealand",
      "currency": "NZD",
      "continent": {
        "code": "OC"
      }
    },
    {
      "name": "Norway",
      "currency": "NOK",
      "continent": {
        "code": "EU"
      }
    },
    {
      "name": "Italy",
      "currency": "EUR",
      "continent": {
        "code": "EU"
      }
    }
  ]
}

Continuing with the above example where the API didn’t return the continent information, you are forced to make another API call GET /continents/{code} that can return you the information about the continent.

{
  "data": {
    "continents": [
      {
        "code": "EU",
        "name": "Europe"
      }
    ]
  }
}

If you are using GraphQL, all of the above API calls can be combined into a single GraphQL request as shown below:

query {
  countries {
    name,
    capital,
    continent {
      name
    }
  }
}

Above query can fetch country name, capital, and continent name in a single response payload.

{
  "countries": [
    {
      "name": "New Zealand",
      "capital": "Wellington",
      "continent": {
        "name": "Oceania"
      }
    },
    {
      "name": "Norway",
      "capital": "Oslo",
      "continent": {
        "name": "Europe"
      }
    },
    {
      "name": "Italy",
      "capital": "Rome",
      "continent": {
        "name": "Europe"
      }
    }
  ]
}

Major Components of GraphQL

Following are the major components of GraphQL APIs.

READ ALSO:  Making HTTP Requests in Blazor WebAssembly Apps

GraphQL Schema

The GraphQL Schema describes the data clients can request using the GraphQL API. It is basically a contract between the client and the server and defines what an API can do and can’t do and how clients can request data using the API. The schema can be defined using the GraphQL Schema Definition Language (SDL) and it describes the object types associated with each node. The following code snippet is an example of a schema and you can see how each element has a type definition associated with it.

type Book {
    id: ID
    title: String
    published: Date
    author: Author
}
type Author {
    id: ID
    name: String
    book: [Book]
}

GraphQL Query

The queries are used to fetch and consume data from the server. While writing GraphQL queries, the client can traverse multiple related objects and their fields to fetch lots of related data in one request, instead of making several round trips. The following is an example of a GraphQL query that asks for a book and author by its ID number.

GraphQL Query Request Example

{
  hero {
    name
    friends {
      name
    }
  }
}

GraphQL Query Response Example

{
  "data": {
    "hero": {
      "name": "Superman",
      "friends": [
        {
          "name": "Spiderman"
        },
        {
          "name": "Batman"
        }
      ]
    }
  }
}

GraphQL Mutations

Mutations allow GraphQL clients to insert, update or delete data on the server. These are pretty much equivalent to POST, PUT, PATCH, or DELETE requests we use in REST APIs. Mutations are defined in GraphQL schema on the server-side and the client can only manipulate data exposed by the mutations.

GraphQL Mutation Definition

mutation AddNewPost ($name: String!, $postType: PostType) {
  addPost(name: $name, postType: $postType) {
    id
    name
    postType
  }
}

GraphQL Mutation Request Example

{
  "name": "Introduction to GraphQL",
  "postType": "ARTICLE"
}

GraphQL Subscriptions

In GraphQL, subscriptions allow a server to send data to its clients, notifying them when events occur. These are usually implemented using WebSockets and can be useful when you want to send real-time notifications from servers to clients. GraphQL subscriptions use an Event-based approach where a client subscribes for some particular events to the server and the server informs the client whenever these events trigger.

READ ALSO:  Full Stack CRUD using Angular 8 and ASP.NET Core 5 Web API

An Example GraphQL Subscription

subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {
  storyLikeSubscribe(input: $input) {
    story {
      likers { count }
      likeSentence { text }
    }
  }
}

GraphQL Resolvers

Resolver is a GraphQL query handler that tells GraphQL how and where to fetch the data corresponding to a given field in the query. Whenever a GraphQL client queries for a particular field, the resolver for that field fetches the requested data from the appropriate data source. These data sources can be databases, microservices, REST APIs, or even other GraphQL queries.  

An Example GraphQL Resolver

Query: {
  book(obj, args, context, info) {
    return context.db.loadBookById(args.id).then(
      bookData => new Book(bookData)
    )
  }
}

Summary

GraphQL has solved a lot of problems using its single round-trip based standardized architecture which is always a better, cheaper, and faster alternative to REST APIs. There are still some shortcomings that are bound to be resolved over time as more and more developers are choosing GraphQL over REST, especially for new projects. If you want to learn how to implement GraphQL APIs then read my post, Getting Started with GraphQL in ASP.NET Core in which I will show you how to build a GraphQL API in ASP.NET Core. I hope you have found this post useful. If you have any comments or suggestions, please leave your comments below. Don’t forget to share this tutorial with your friends or community.

This Post Has 3 Comments

  1. Taofeek LASISI

    I hope in the future, you will be doing a PDF downloadable versions of your posts for reading offline.

  2. Carlo

    Hi,

    I like your articles, but I tend to print them out.
    The problem is the Black background on the Console screen grabs. They do not print well.

    IS there any chance they could be but in White background? I know this is a big ask.

    You can change the background of any terminal – just by going into the settings.

    Thanks
    Carlo

  3. Bilbo Baggins

    Awesome article! Provides a clear introduction to GraphQL, its advantages over REST API and its major components. Looking forward for more articles on this.

Leave a Reply