What is GraphQL?
Tags: webdev, graphql, api
Published: 2020-03-18 15:50:39

_📣 This post originally appeared as [What is GraphQL?](https://blog.bearer.sh/what-is-graphql-api/) on [The Bearer Blog](https://blog.bearer.sh)._
<!--kg-card-begin: markdown-->

GraphQL is a query language for APIs and a set of tools that enable sending and processing queries. While originally developed at Facebook, it has since grown beyond the social network's specific use case. Essentially, the client describes the type of data they want, and the server delivers only that data. At Bearer, [we use GraphQL internally](https://blog.bearer.sh/lessons-learned-from-graphql/) to drive our dashboard.

You can even think of GraphQL as a layer that sits on top of your resources, such as databases and third-party APIs. Much like [REST APIs](https://blog.bearer.sh/what-is-a-rest-api/) act as a unified way for clients to request data, GraphQL takes it a step further. Clients describe the shape of the response, so they are never surprised by the data that comes back from a GraphQL server.

## Benefits of GraphQL

[REST](https://blog.bearer.sh/what-is-a-rest-api/) has been the default choice for APIs for quite some time. So why change? GraphQL doesn't replace REST, but instead offers an alternative type of API technology. It us currently being used in production by companies like GitHub, Facebook, AirBnB, Shopify, and [Bearer](https://bearer.sh). Some benefits include:

-   **Clients receive only the data they ask for**. Instead of endpoints that return full objects, the clients in GraphQL can specify just the properties they want. As a bonus, this results in lower bandwidth usage.
-   **Retrieve multiple resources in a single request**. Let's say you have a social page with a list of the user's friends, but you also want friends lists for each of those users. GraphQL queries let you follow references between resources.
-   **A type system**. Even if the language of your client or server isn't explicitly typed, GraphQL is. This adds another layer of assurance that the data the client expects is the available data.
-   **Introspection**: GraphQL allows clients to inspect the schema through a technique called introspection. Special fields, such as `__schema` can be queried to provide detailed information about the API.

To get a better understanding of how it all works, it is useful to first look at the anatomy of a GraphQL API.

## Anatomy of GraphQL

When we talk about _using_ GraphQL, we're talking about clients talking to servers. The [full specification](http://spec.graphql.org/June2018/) includes many details on the language, but as an overview we can focus on three core parts: the schema, queries, and resolvers.

### The Schema

GraphQL's schema is the core of the _query language_. It all centers around a [detailed type system](https://graphql.org/learn/schema/). The shape of all data, requests, and responses are defined as part of the system.

```graphql
type User {
  name: String!
  id: ID!
  friends: [User]!
}
```

The type system contains a variety of built-in types, like `String` and `ID` above. You can also define your own. In the example, we define a `User` type. It contains a name of type `String`. The exclamation point `!` denotes a required field. We also define a field of `friends` that contains a list of other `User`s.

### Queries and mutations

Clients interact with the server by sending queries and mutations. A **query reads data**, similar in use to a `GET` request. A **mutation writes data**, similar to `POST`, `PUT`, or `DELETE`. Relating queries and mutation to the HTTP verbs we're familiar with can be useful when thinking about

To perform a query, it first needs to be added to the schema.

```graphql
type Query {
  user: User
  users: [User]
}
```

This is a special `Query` type used to define the type of data we expose to clients. You can then query for a list of all users and their friends.

```graphql
{
  users {
    name
    friends {
      name
    }
  }
}
```

Notice that we are only requesting the `name` of each friend. GraphQL knows that `friends` is a list, or array, of `User`. This means we can request just a portion of `User`, or if we wanted to, nest it further and request the friends of friends. The client can send this query to the server, where it is executed. The result, depending on the server implementation, is a JSON response that may look something like the following:

```json
{
  "data": {
    "users": [
      {
        "name": "Sara",
        "friends": [
          {
            "name": "Steve"
          }
        ]
      }
    ]
  }
}
```

This works for retrieving data, but for creating or modifying we use a **mutation**. Mutations look similar to queries.

```graphql
type Mutation {
  addUser(name: String!): User
}
```

This mutation creates a new user and takes the user's name as a _required_ argument. It then returns the `User` type. To call this mutation, we can write a request like this:

```graphql
mutation {
  addUser(name: "Alex") {
    name
    id
  }
}
```

Here we add a new user with the name of "Alex" and ask for the created user's `name` and `id` in the response. GraphQL lets you specify what parts you want back, even during _writes_. No need to query the user individually for the updated details. The response from the server will look something like this:

```json
{
  "data": {
    "addUser": {
      "name": "Alex",
      "id": "1"
    }
  }
}
```

But how does our server know where the data is coming from? That is where resolvers come in.

### Resolvers

Resolvers are GraphQL's way of mapping data onto queries and mutations. The data can come from anywhere. Databases, third-party APIs, or even static objects. How resolvers are implemented depends on the language and server, but they roughly look like this:

```js
// In Apollo Server (Javascript)
const resolvers = {
  Query: {
    users: () => db.users.getAll() // Example db request
  }
}
```

These resolvers, when configured with your schema, will map properties between the defined _types_ in the schema and the properties on the returned object. Meaning, even if `db.users.getAll()` returns more than the information requested when the `users` query is called, the GraphQL server will only send the pieces that were requested.

## Disadvantages

GraphQL is not without its disadvantages.

-   **Repetition**: The type system increases boilerplate code. When combined with a typed language, developers may find that they are essentially rewriting existing types just for GraphQL. Some tools alleviate this, like [`graphql-codegen`](https://graphql-code-generator.com/). This excess code is primarily a concern of the server. Clients aren't required to re-define the full type system.
-   **Lack of built-in authentication conventions**: GraphQL recommends moving authorization and authentication to a separate business-logic layer. In some cases, applications will use a mix of REST and GraphQL. REST to handle log-in flows, and GraphQL to handle the data fetching.
-   **Different error practices**: Clients are accustomed, in HTTP, to receiving [http status codes](https://blog.bearer.sh/common-http-status-codes/) that describe responses. All GraphQL responses are status `200`. If a query is unsuccessful, the returned JSON will include an `errors` key instead of `data`.
-   **Lack of built-in caching**: Since GraphQL requests all hit the same endpoint, standard client caching doesn't work as it does with REST. As a result, servers and clients need to rely on their own system to handle serving cached data.

## Ecosystem

Perhaps the most alluring thing about GraphQL, and part of its fast adoption, is the ecosystem. Many projects adopt a modern, developer-friendly approach to setup and configuration. Tools like [GraphiQL](https://github.com/graphql/graphiql) make exploring an API easy, and easy to document. Server ecosystems like [Apollo](https://www.apollographql.com/) allow users to get up and running easier, as well as allow large teams to scale their GraphQL usage. Other approaches, like [Prisma](https://www.prisma.io/) aim to abstract away the database. There are even excellent examples of GraphQL-as-a-service, like [Fauna](https://fauna.com/).

## Where to go from here

We've only touched the surface on what GraphQL can do. A great place to begin is [the official site](https://graphql.org/), and if you want more technical specifications the [GraphQL spec](http://spec.graphql.org/) is available for viewing. Platforms like [Apollo](https://www.apollographql.com/) and [Hasura](http://hasura.io/learn) also offer excellent tutorials on core GraphQL concepts and their tools. To begin implementing GraphQL in your preferred stack try these libraries:

-   [graphql-ruby](https://graphql-ruby.org/) (Ruby)
-   [Apollo](https://www.apollographql.com/) (Node.js)
-   [Absinthe](http://absinthe-graphql.org/) (Elixer)
-   [Graphene](https://graphene-python.org/) (Python)
-   [graphql-go](https://github.com/graphql-go/graphql) (Go / Golang)

Are you using GraphQL in your organization? Let us know by connecting [@BearerSH](https://twitter.com/bearersh) and check the [Bearer Blog](https://blog.bearer.sh/) for articles.

<!--kg-card-end: markdown-->