Fragments are one of the most underrated features in GraphQL. A fragment is a reusable unit in GraphQL that allows developers to construct sets of fields that you can include in multiple operations. Fragments are helpful when constructing queries that require repetitive fields or complex data structures that need to be broken down into smaller chunks. Some GraphQL clients even allow you to use fragments to colocate fragments across pages and components.

In this blog post, you'll learn how to use GraphQL fragments and how to use them to construct operations that return data from GraphQL unions and interfaces.

When to use GraphQL fragments?

Using fragments, we can keep our queries concise and avoid repeating the same fields multiple times. Additionally, if we need to add or remove fields from our query, we only need to update the fragment instead of modifying every instance of the fields in the query.

Let's have a look at the following GraphQL schema:

type Employee {
  name: String
  age: Int
  salary: Float
  terminationDate: String
}

type Query {
  employees: [Employee]
}

In this schema, the response type for employees is Employee, which returns the employee's name, age, salary, and termination date. The terminationDate field is only returned for employees that have left the company.

Assume you have a page that displays a list of employees with their names, ages, and salaries. You can create a fragment that includes those fields and use it like this:

fragment employeeFields on Employee {
  name
  age
  salary
}

query {
  employees {
    ...employeeFields
  }
}

This makes constructing operations that return data from multiple types easier. For example, when adding a new field selection that returns the same fields, you can simplify using a fragment:

fragment employeeFields on Employee {
  name
  age
  salary
}

query employees {
  employees {
    ...employeeFields
  }
  allEmployees: employees {
    ...employeeFields
    terminationDate
  }
}

In the above example, we request the same fields for employees and allEmployees. The field allEmployees is an alias for employees and returns the same data. The only difference is that allEmployees returns the terminationDate field. Instead of repeating the same fields in both queries, we can use the employeeFields fragment to keep our operations concise and avoid repeating the same fields multiple times.

To read more about basic GraphQL fragments, check out this previous blog post.

In the next section, you'll learn how to use GraphQL fragments based on interfaces.

Fragments for interfaces

You've just learned how to use GraphQL fragments to share fields between field selections, but you can also use fragments on fields defined through an interface. If we'd create an Employee interface, we could create a fragment based on that interface instead of the return type for an operation. This is useful when you have multiple types implementing the same interface.

For example, in the following GraphQL schema we have changed the type Employee to an interface that is implemented by two new types: CurrentEmployee and FormerEmployee.

interface Employee {
    name: String
    age: Int
    salary: Float
}

type CurrentEmployee implements Employee {
    name: String
    age: Int
    salary: Float
}

type FormerEmployee implements Employee {
    name: String
    age: Int
    salary: Float
    terminationDate: String
}

type Query {
  formerEmployees: [FormerEmployee]
  currentEmployees: [CurrentEmployee]
}

In this schema, the Employee interface is implemented by CurrentEmployee and FormerEmployee. The formerEmployees and currentEmployees fields return a list of former and current employees, respectively. Let's say we want to get current and former employees and display their names, ages, and salaries. We can use a fragment to share the fields between formerEmployees and currentEmployees:

fragment employeeFields on Employee {
  name
  age
  salary
}

query {
  formerEmployees {
    ...employeeFields
    terminationDate
  }
  currentEmployees {
    ...employeeFields
  }
}

That's not all; you can also use fragments to distinguish between possible return types for an operation that returns a union (or interface) type , as you'll learn in the next section.

Fragments for unions

What if we'd want to get both the former and current employees in one field selection and want to distinguish between the fields? In GraphQL, you can do this by using inline fragments. Have a look at the following GraphQL schema that contains a union type:

interface Employee {
    name: String
    age: Int
    salary: Float
}

type CurrentEmployee implements Employee {
  name: String
  age: Int
  salary: Float
}

type FormerEmployee implements Employee {
  name: String
  age: Int
  salary: Float
  terminationDate: String
}

union AnyEmployee = CurrentEmployee | FormerEmployee

type Query {
  employees: [AnyEmployee]
}

The above schema shows that the AnyEmployee union type contains two possible types: CurrentEmployee and FormerEmployee. Let's say we want to query the employees' field and display different information depending on whether an employee is employed or a former employee. We can use an inline fragment to specify the fields unique to each subtype of the AnyEmployee union.

query {
  employees {
    ... on Employee {
      name
      age
      salary
    }
    ... on FormerEmployee {
      terminationDate
    }
  }
}

In this example, we're requesting the employees field and requesting the name, age, and salary fields for all employees. Additionally, we're using an inline fragment with the on keyword to specify that if an employee is a FormerEmployee, we also want to include the terminationDate field in the response. Three or four fields will be returned based on whether or not an employee is currently working for the company.

Using inline fragments in GraphQL Explorer

Using an inline fragment, we can conditionally include fields based on the type of object you're querying, making it easier to work with union types and polymorphic interfaces.

Running the example

You should install the StepZen CLI on your local machine to run the example in this blog post. If you still need to install StepZen, you can follow the instructions in the Getting Started guide.

To run the example, you'll need to define a schema for the GraphQL API in a new file called api.graphql. Create this file in a new directory, copy the schema from the example above, and paste it into the api.graphql file. Add the @rest custom directive to mock data. The complete schema, including the mocking capability, looks like this:

## api.graphql

## ...

type Query {
  employees: [AnyEmployee]
    @rest(
        endpoint: "stepzen:empty"
        ecmascript: """
          function transformREST(s) {
            return ([
              {
                __typename: "FormerEmployee",
                name: "John Doe",
                age: 30,
                salary: 100000,
                terminationDate: "2021-01-01"
              },
              {
                __typename: "CurrentEmployee",
                name: "Jane Doe",
                age: 25,
                salary: 80000
              },
              {
                __typename: "CurrentEmployee",
                name: "John Smith",
                age: 40,
                salary: 120000
              },
              {
                __typename: "FormerEmployee",
                name: "Jane Smith",
                age: 35,
                salary: 100000,
                terminationDate: "2021-01-01"
              }
            ])
          }
        """
    )
}

Next, you'll need to create a new file called index.graphql and add the following query to it:

## index.graphql
schema @sdl(files: ["api.graphql"]) {
  query: Query
}

Now you can run the following command to start and deploy the StepZen GraphQL API:

stepzen start

If you'd like to implement the example for interfaces, you should create the formerEmployees and currentEmployees operation fields using the logic for the employees operation field.

The StepZen CLI will ask how you like to name your endpoint, after which it will be deployed. Your new GraphQL API is now running, and you can open GraphQL Explorer to test the queries from this blog post on the endpoint displayed in the terminal.

Conclusion

In this blog post, you've learned to use GraphQL fragments to share fields between fields selection. You've also learned to use fragments to construct queries that return data from GraphQL unions and interfaces. Questions? You can ask for help on our Discord channel.