How to query your schema with GraphQL fragments

David Mráz

What is GraphQL fragment

First, we have to answer the question, "what is a fragment"?

A fragment is basically a reusable piece of query.

In GraphQL, you often need to query for the same data fields in different queries. The code to define these fields has to be written multiple times, leading to more errors. By reusing this code, we can be more efficient with our time and reuse these pieces of query logic on different queries. But how we can use it in GraphQL? Let’s say we want to use the same query as in this article on aliases.

How to use GraphQL fragments

You can start by cloning our example repository

git clone git@github.com:atherosai/graphql-gateway-apollo-express.git

install dependencies with

npm i

and start the server in development with

npm run dev

Then you should be able to access GraphQL Playground. You should then be able to execute the query where the aliases concept is used:

query getUsers {
admins: users(role: ADMIN) {
id
firstName
lastName
phone
username
}
accountants: users(role: ACCOUNTANT) {
id
firstName
lastName
phone
username
}
}

We can see, there’s still room for improvement, as the fields of each query are repeated multiple times. Since they are the same selection set, we can define the fields just once then reference them as needed. For that purpose we can use a fragment. Every fragment consists of different parts. Let’s take a look at this example of a simple fragment:

fragment userFields on User {
id
firstName
lastName
phone
username
}

Each fragment contains the name of the fragment (userFields), to what type we are applying this fragment (User) and the selection set id, firstName, lastName, phone and username.

Now we can rewrite the getUsers query with the userFields fragment and spread operator.

query getUsers {
admins: users(role: admin) {
...userFields
}
accountants: users(role: accountant) {
...userFields
}
}
fragment userFields on User {
id
firstName
lastName
phone
username
}

The results are the same, but in terms of refactoring and code reuse, there are many advantages to writing queries this way.

Inline fragments

Inline fragments are useful for queries in which we have to resolve the type at runtime. We also use inline fragments when we need to implement one of the abstract types in GraphQL (i.e.,Union or Interface). The most common example of an interface is the node interface, as we discussed in the module on Interfaces. A Union is typically used for search implementation in GraphQL. When we query for these types, we have to use an inline fragment to conditionally execute. This search query illustrates how this inline fragment can look:

query searchQuery {
search(query: "Atheros") {
... on User {
email
firstName
lastName
}
... on Company {
name
vatId
}
}
}

Statements on User and on Company are the type conditions. With type conditions we are able to apply each fragment on different type in the schema even that both types User and Company have different fields.

Conclusion

In other cases, the fragments are also frequently used in frontend caching clients like relay or apollo. In relay we have the so-called fragment container, which defines the component’s data requirements of the component. In the apollo-client, we use the concept of fragments for the so-called queries collocation. Fragments in these caching clients are basically perfect matches for the data needs of the UI components. This can be used to our advantage for static typing with Flow or TypeScript. We can generate TypeScript or Flow definitions from our GraphQL schema and use these definitions as the prop type definition for our UI component. One of the best tool for this is GraphQL CodeGen.

Did you like this post? The repository with the examples and project set-up can be cloned here. Feel free to send any questions about the topic to david@atheros.ai.

Join thousands of others and be occasionally notified about new articles and our courses

* Signing up for Atheros newsletter indicates you agree with Terms and Conditions and Privacy Policy including our Cookie Policy.