How To Use Fragments To Clean Up Your GraphQL Schemas
Tags: graphql, todayilearned, discuss, tutorial
Published: 2021-07-12 16:31:17

_Originally posted on [StepZen](https://stepzen.com/blog/how-to-use-fragments-to-clean-up-your-graphql-schemas)_

If you've written multiple GraphQL queries before, you know that duplicated code builds up fast. Luckily, the GraphQL spec has defined Fragments to help you trim down your code, and StepZen has a tool to help you do it with speed!

> Note: This tutorial assumes the prerequisite of basic GraphQL knowledge: types and queries. You can read up on them on the [official specification site](https://spec.graphql.org/draft/#sec-Type-System).

## What are GraphQL Fragments?

Glad you asked! Basically, GraphQL Fragments help developers stick to the [Don't Repeat Yourself](https://en.wikipedia.org/wiki/Don't_repeat_yourself) principle.

According to [the official spec](https://spec.graphql.org/June2018/#sec-Language.Fragments), GraphQL Fragments are

> "the primary unit of composition in GraphQL."

That means they're elemental, atomic-- you can't reduce the code further down. So using them means eliminating duplicated code.

But it's one thing to know what Fragments are in theory, and another to use them in practice. Let's get cracking!

If you want to follow along with me, you'll need a couple things.

1. A [StepZen account](https://stepzen.com/request-invite) to access admin and API keys.
2. A familiarity with the [The Cat API](https://docs.thecatapi.com/1.0/authentication) (you'll need a free account to get access to the key)

## Our Example Schemas

Our example schemas are three files under one folder.

### `breed.graphql`

```graphql
type Breed {
  temperament: String!
  origin: String!
  name: String
  life_span: String
  hairless: Int
  rare: Int
}

type Query {

  BreedById(id: String!): Breed
    @rest(
      endpoint: "https://api.thecatapi.com/v1/breeds/search?q=$id"
      configuration: "cat_config"
    )
  allBreeds: [Breed]
      @rest(
      endpoint: "https://api.thecatapi.com/v1/breeds"
      configuration: "cat_config"
    )
}

```
`breed.graphql` defines our Breed type as well as our two queries, `BreedById` and `allBreeds`. They retrieve data from Cat API endpoints, specified in StepZen's custom directive, `@rest`.

> To learn more about `@rest`, check out [our docs](https://stepzen.com/docs).

You'll notice a `cat_config` name on both queries' `configuration` specification.

This refers to the configuration defined in the next file:

### `config.yaml`

```yaml
configurationset:
  - configuration:
      name: cat_config
      Authorization: Apikey {{YOUR_CAT_CONFIG_KEY_HERE}}
```

`config.yaml` contains the information StepZen needs to connect to the Cat API.

Lastly, we have:

### `index.graphql`

```graphql
schema @sdl(files: ["breed.graphql"]) {
  query: Query
}
```

## Opening Up the StepZen Schema Explorer

StepZen has a custom graphiQL query explorer that we can use to query the StepZen endpoint. There are all kinds of yummy features in the StepZen Schema Explorer, but today we're going to focus on the fragment button.

To open the Explorer, run `stepzen start` from the command line. If you've never used StepZen before, you might have to run `stepzen login` first and provide your credentials.

The StepZen Schema Explorer will open up in your browser! Click 'Explorer' -> select 'BreedById' and 'allBreeds' and select all the available fields. Hit the arrow button next to the StepZen logo, and you'll get your results back!

![json results screenshot](https://codimd.s3.shivering-isles.com/demo/uploads/upload_42b4c08c35e0b0131ec96a98f3307291.png)

Now, since we're requesting all fields on both queries, we have an opportunity to use Fragments!

Normally, you'd have to go back into `breed.graphql` and write something like:

```graphql
fragment breedFields on Breed {
  temperament
  origin
  name
  life_span
  hairless
  rare
}
```
...but that's not necessary with the StepZen query editor!
If you hover over the query name, you can see a button with ellipses, ( `...` ) on it.

![query screenshot](https://codimd.s3.shivering-isles.com/demo/uploads/upload_49a95fab8ed337222f3ab9badf5c9da0.png)

Click it, and you'll the see the Fragment's been generated for you, right there in the Explorer!


![query screenshot](https://codimd.s3.shivering-isles.com/demo/uploads/upload_4dd3fec39173103a51e495f27f185566.png)

Now de-select all your fields on `allBreeds` and select `BreedFragment`.

Run your query again, and you'll get the exact results you need! ![](https://codimd.s3.shivering-isles.com/demo/uploads/upload_5a29c5a65ab741ede3662ddd5470a2ee.png)

Notice that you can also _edit_ your fragment by selecting and de-selecting fields:

![](https://codimd.s3.shivering-isles.com/demo/uploads/upload_2621acb1f85ded2cc48f395b5ee199ca.png)

This is super convenient because if you add a field in your schema, say, `country_code`, then all it takes is one click of a mouse to add it, not just to your fragment definitions, but to all your previous queries in the browser.

So adding `country_code`:

```graphql
type Breed {
  temperament: String!
  origin: String!
  name: String
  life_span: String
  hairless: Int
  rare: Int
  country_code: String
}
```

Doesn't require going in and adding altnames to each query like:

```graphql
query MyQuery {
  BreedById(id: "abys") {
    temperament
    rare
    hairless
    life_span
    name
    origin
    country_code
  }
  allBreeds {
    temperament
    rare
    hairless
    life_span
    name
    origin
    country_code
  }
}

fragment BreedFragment on Breed {
  temperament
  rare
  hairless
  life_span
  name
  origin
  country_code
}

```
All you have to do is click on `country_code` in your Breed fragment and this code:

```graphql
query MyQuery {
  BreedById(id: "abys") {
    ...BreedFragment
    rare
  }
  allBreeds {
    ...BreedFragment
  }
}

fragment BreedFragment on Breed {
  temperament
  rare
  hairless
  life_span
  name
  origin
  country_code
}
```

Will auto-fill the resulting JSON alt names in each query for you:

```json
{
  "data": {
    "BreedById": {
      "country_code": "EG",
      "hairless": 0,
      "life_span": "14 - 15",
      "name": "Abyssinian",
      "origin": "Egypt",
      "rare": 0,
      "temperament": "Active, Energetic, Independent, Intelligent, Gentle"
    }, {...} etc
```

## Where To Go From Here

I hope you've enjoyed learning how to speed up your GraphQL coding experience!

If you're interested in StepZen's other features, you can check out our docs on our StepZen Schema Explorer. There are lots of other ways to streamline your coding experience there, including an exporter that helps you generate Apollo and Gatsby client code, a schema template exporter, and a documentation tab.

Please let us know what you're up to with StepZen! We'd love to hear about it on [Discord](LINK_NEEDED) or [Twitter](https://twitter.com/stepzen_dev).