How to Use GraphQL Fragments

graphql fragments

This is a complimentary blog post to a video from the ShopifyDevs YouTube channel. In this article, Chuck Kosman, a Launch Engineer at Shopify Plus, will walk you through some key features of GraphQL that are useful for building applications at scale. This is the third article in a five-part series of tutorials designed to educate and improve your knowledge of the benefits of GraphQL.

In this tutorial, Chuck will explore GraphQL fragments, which are a way to reuse fields. He will discuss what fragments are, how to define them, and how to use them.

Note: All images in this article are hyperlinked to the associated timestamps of the YouTube video, so you can click on them for more information.

Creating multiple fields with GraphQL

In the third part of this GraphQL language features tutorial, we're going to be looking at fragments, which are a way to reuse fields. In the previous tutorial on how to use GraphQL aliases, we looked at what aliases could do. We’ll be picking up where we left on part two of the tutorial. You can also step back and read up on what is GraphQL if you’d like an overview of getting started and the language itself.

If you didn't watch the aliases tutorial, here I have a query with no operation name where I'm using aliases to distinguish between one product field and another product field with two different ids.

graphql fragments: gif taken from youtube video

Now, what you might immediately notice about this is that it's somewhat redundant. I want the same information on both of these products, product1 and product2, but I've had to write title and description a couple of times.

It would be nice if I could recycle those fields into a common definition, so that I could reference that common definition, and I don’t have to type out title and description. This would be especially useful if I'm working at scale and I need to get these fields a number of different times.

I don't want to have to update the fields that I want in multiple different places. I just want to define them once. 

Fragments to the rescue! They allow us to do exactly that.

The syntax: writing fragments in GraphQL

The fragment syntax looks like this:

graphql fragments: gif taken from youtube video

Just below the query we’re going to use the fragment keyword. We’re going to name the fragment, let’s call it TitleAndDescription. We also have to specify on what type this fragment can apply. The syntax for that is using the on keyword, and then I specify what type. So I know that when I issue a request for the product fields, that returns me type product.

If I didn't know that, in GraphiQL here, if I hover over that and it says the type that I get back is Product, capital P. So I'm going to write Product and it’s actually going to autocomplete for me.

graphql fragments: gif taken from youtube video

I'm going to open curly braces and I'm going to specify the fields just like I was getting fields on a product type, so I'll write title and description.

Now, up here, the way that we’re actually going to say we want to use this fragment in terms of the return fields is with an ellipsis (...). So, three dots, and then we’ll reference the name of the fragment itself. So let's say ...TitleAndDescription and we’ll do that in both places.

graphql fragments: gif taken from youtube video

Now when we issue this query, we’re actually expecting to get exactly the same information back. So title and description on alias product1 and alias product2, and indeed I do.

You might also like: How to Use GraphQL Aliases.

Where this really shines at scale is if we wanted to add another field here, we’re going to browse the product documentation for another field.

Let's say I needed the featured image and I needed that featured image's id, I’d only have to define it once. I wouldn’t have to go into each reference of each time I’ve used it to do that.

I'm going to issue this query and I get the ids back of those. So in this syntax, we've defined the fragment using the fragment keyword, and then substituted that fragment in for fields over here.

graphql fragments: gif taken from youtube video

Inline fragments: what are they and how can they help you? 

There’s another way to use fragments called inline fragments. These tend to be quite useful if the schema that you're working with implements either interfaces or unions. All that a union means in a schema is that a field could return more than one different type.

Let's say in Shopify schema there’s a place where I wasn't just expecting product back, but I could also get a collection back, or a customer back. Interfaces are somewhat similar and they're used in GraphQL schemas when multiple different types have the same fields on them.

What we would say is that in Shopify schema, there's an “abstract type”, that's what GraphQL calls it, called a node, and there are many other types that implement the node interface.

Just to show you what I'm talking about, I'm going to flip to the Shopify documentation of the node type in the admin API. There's node and it's defined as an interface. The only field that this interface actually uses is ID.

graphql fragments: gif taken from youtube video

But many different types actually implement node. Many different types of entities on Shopify need to have an id associated with them. This includes quite a lot of things, including orders, products, and customers, among other things.

I'm going to flip to a different piece of the Shopify documentation to show you where inline fragments are quite useful when working with interfaces.

I'm going to flip to the documentation of this mutation called tagsAdd.

You might also like: How to Build a Shopify App in One Week.

Using tagsAdd as an example

graphql fragments: screenshot of the tagsAdd documentation

I want you to notice a couple of things about this interactive example of tagsAdd.

tagsAdd is a mutation that, as the name suggests, allows you to add tags to a taggable object.

How does it do this?

It allows you to specify the id of the entity to which you want to add these tags, but what it does is it returns a node when you have done this. Now, the only field on node is ID, so what if you know that you are tagging a product and you want that product's details back beyond its id when you have completed this operation?

What we’re going to do, just for ease of use, is we’re going to copy and paste this example because it's a pretty good one. It gets you everything that you need to get up and running. So first let’s copy-paste this, flip back to my store, and completely remove this query.

graphql fragments: gif taken from youtube video

The compliment to this is that I'm also going to use these variables down here. 

Now, that id is not going to work, I'm going to substitute in the id of a product that I know I have on this particular test store. Let’s say I want to tag this product as on-sale. We can add this tag for whatever merchandising or reporting purposes the rest of my applications have.

graphql fragments: gif taken from youtube video

I'm actually not going to run this query just yet. 

What I'm going to say is: OK, well, I get this node back, but I also want to know the complete list of tags that come back on this node. I also want to know the title of the product. 

You’ll notice something is off already because GraphQL is not auto-completing either tags or titles for me. But let's say I naively wrote this in an application and I wanted to do this.

graphql fragments: gif taken from youtube video

It says, "Hey, fields title doesn't exist on node." Well, that's weird. I know that I have just tagged a product. I know that the id that I've supplied is that of a product. And I know products have a title, and I know that there's a property in them called tags if I were to export to schema.

What's going on here?

Well, the product type implements node.

You might also like: How to Use GraphQL Operation Names and Variables.

Clarifying terminology: defining inline fragments

What I need to say is, if a product type is the type that comes back, tell me about those specific fields and products. So, I'm going to use the inline fragment on this syntax just to show you the difference here.

 graphql fragments: gif taken from youtube video

Like regular fragments, I'm going to start with a ... and the syntax here is going to look like this. I'm going to say ...on Product, open curly braces, and then I'm just going to move the title and tags fields into this inline fragment.

It's almost like an anonymous fragment where I've just defined it right inside of the fields.

Now, when I issue this mutation for tagsAdd, I get all the data that I expect back.

graphql fragments: gif taken from youtube video

It’s saying on this node, there's the id, that id belongs to the node interface. Then the title and tags that don't belong to the node interface I've retrieved because I've used an inline fragment.

Basically to recap, this says if the node returned is a product, also fetch the title and tags fields.

Now, the tagsAdd mutation in this particular case can operate on any node. So if I were to say add tags to customer and I don't know ahead of time when I use this mutation in my application if I'm going to get a product back or a customer back, and/or I want different fields based on which of those comes back, I could define another inline fragment to say ...on Customer and then maybe I'd want their email and I could drill into their addresses, for example.

Again, this syntax is called an inline fragment, which is very useful when the schema that you're working with uses either union or interface types as part of its schema.

Thanks for joining me for part three of this GraphQL language features tutorial. In the next part, we're going to be looking at what working with pagination looks like in GraphQL.

Stay tuned for part four of this five-part tutorial where we'll be looking at another feature for working at scale: pagination in GraphQL. If you missed it, you can start at the beginning of this series with GraphQL operation names and variables.

Grow your business with the Shopify Partner Program

Learn more