GraphQL Unions – Customize your results!
Tags: graphql, unions, apollo
Published: 2021-05-09 20:43:19

What's not to love about [GraphQL](https://graphql.org/)? It's got your back when it comes to returning predictable results - the data you get is exactly what you need, nothing more and nothing less.

If you’ve worked with GraphQL, then you’re probably familiar with query and mutation types — so what exactly is a GraphQL union? 🤔

> Unions are abstract GraphQL types that enable a schema field to return one of multiple object types.

Not really sure what that means? Don't worry! I got you. In this tutorial, I will be walking you through the concept of GraphQL **unions** by addressing the two important questions below:

- Why do I need GraphQL unions?
- How do I implement GraphQL unions?  

<br>

## Why do I need GraphQL unions?

Let's consider a simple scenario: You own a small candy shop and the website is using GraphQL APIs. Each candy is associated with a unique identifier, it's name and price.

![Object type for candy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msk0cw8h6an3lpdm5x06.png)

Now, let's have a basic query in place to retrieve the details of the candy when passed the unique identifier. Here's how that's gonna look:

![GraphQL query for candy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kk12ipgcxylzbjbaqzwy.png)

Building on this scenario, let's assume that it's also possible for a queried candy to either be out of stock or unavailable for shipping in the region. We can visualize this as three three states of a candy:

![States of a candy – In Stock, Out of Stock and Region Unavailability](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmtyeyzo8wo5sholzzih.png)

We will consider all three states as valid responses and hence, instead of throwing an error when a candy is out of stock or unavailable for shipping, we provide the user with additional information like when a candy would be restocked if out of stock and an array of regions where it is available if unavailable for shipping.

Now, if we add all these new fields on our existing type: Candy, then we would have to over-fetch data to determine the state of a candy. And if we create separate queries for the different states, we would be under-fetching data.

In essence, what we're itching for is a way to somehow define 'out of stock' and 'region unavailability' as separate types (say,  `OutOfStock` and `RegionUnavailability` ) along with the existing type: `Candy` under the same query to ensure we're only getting the data we need.

{% gist https://gist.github.com/rohinivsenthil/c1b9d67fbfe4263f568b97cfaa3407f1 %}

How do we do this? That's right, this is where GraphQL unions steps in. We model the identified "states" as separate types and use unions to enable a query to return one of the multiple types defined.

<br>

## How do I implement GraphQL unions?

Now that we have our states as object types. Let's understand unions: **Unions** are abstract schema types. To define a union type, we declare which object types are included in the union.
```javascript
union CandyResult = Candy | OutOfStock | RegionUnavailability
```

It's important to understand here that all of a union's included types *must* be object types (not scalars, input types, etc.) and that the included types do *not* need to share any fields.

#### Resolving a GraphQL union (server-side):

After adding the union type to our schema file, it's going to be looking something like this:

{% gist https://gist.github.com/rohinivsenthil/20367c3d77d952eac2650975dca2ed5a %}

To resolve a union, we are required to specify which of the union’s type is being returned. To achieve this, we define a `__resolveType` function for the union.

The `__resolveType` function uses a returned object's unique field to determine its type. It then returns the name of that type as a string.

Here’s how we would use the `__resolveType` function for the CandyResult union we’ve defined in the schema:

{% gist https://gist.github.com/rohinivsenthil/19de2c167e317861b194a4a5df65b33e %}

#### Querying for a GraphQL union (client-side):

When the return type of a query is a union, the GraphQL client doesn’t know which object type a field will return. To account for this, a query can include the subfields of multiple possible types.

Here’s how our query going to be looking:
```javascript
query {
  candy(id: $id) {
    ... on Candy {
      name
      price
    }
    ... on OutOfStock {
      restockDate
    }
    ... on RegionUnavailability {
      availableRegions
    }
  }
}
```

Let’s add a candy to our data dump that’s out of stock with a `restockDate` key. When we use the query above to retrieve data for the candy, we can now expect to see the results tailored to exactly what we need.

![Out of Stock Query](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slhglrfrzsrnnkg85vfz.png)

And that’s it! — we’ve made a query that supports multiple object types with the help of unions.

You can find the entire code as a Github repository [here](https://github.com/rohinivsenthil/graphql-unions) 🚀

Share if you found this useful 😄