Ask a Question

GraphQL Fragments

A GraphQL fragment is a reusable unit of logic that can be shared between multiple queries and mutations. Here, we declare a postData fragment that can be used with any Post object:

fragment postData on Post {
  id
  title
  text
  author {
    username
    displayName
  }
}

The fragment has a subset of the fields from its associated type. In the above example, the Post type must declare all the fields present in the postData fragment for it be valid.

We can include the postData fragment in any number of queries and mutations as shown below.

query allPosts {
  queryPost(order: { desc: title }) {
    ...postData
  }
}
mutation addPost($post: AddPostInput!) {
  addPost(input: [$post]) {
    post {
      ...postData
    }
  }
}

The above request is equivalent to:

query allPosts {
  queryPost(order: { desc: title }) {
    id
    title
    text
    author {
      username
      displayName
    }
  }
}

mutation addPost($post: AddPostInput!) {
  addPost(input: [$post]) {
    post {
      id
      title
      text
      author {
        username
        displayName
      }
    }
  }
}

Example :

fragment postData on Post {
  id
  title
  text
  author {
    username
    displayName
  }
}
mutation addPost($post: AddPostInput!) {
  addPost(input: [$post]) {
    post {
      ...postData
    }
  }
}

Variable:

{
	"post": {
    "text": "Hello World",
		"title": "First Blog post",
		"author": [{
			"username": "arijit_ad",
			"displayName": "Arijit Das"
		}]
	}
}

Result:

{
  "addPost": {
    "post": [
      {
        "id": "0x27e0",
        "title": "First Blog post",
        "text": "Hello World",
        "author": [
          {
            "username": "arijit_ad",
            "displayName": "Arijit Das"
          }
        ]
      }
    ]
  }
}

Using fragments with interfaces

It is possible to define fragments on interfaces. Here’s an example of a query that includes in-line fragments:

Schema:

interface Employee {
    ename: String!
}
interface Character {
    id: ID!
    name: String! @search(by: [exact])
}
type Human implements Character & Employee {
    totalCredits: Float
}
type Droid implements Character {
    primaryFunction: String
}

Query:

query allCharacters {
  queryCharacter {
    name
    __typename
    ... on Human {
      totalCredits
    }
    ... on Droid {
      primaryFunction
    }
  }
}

The allCharacters query returns a list of Character objects. Since Human and Droid implements the Character interface, the fields in the result would be returned according to the type of object.

Result:

{
  "data": {
    "queryCharacter": [
      {
        "name": "Human1",
        "__typename": "Human",
        "totalCredits": 200.23
      },
      {
        "name": "Human2",
        "__typename": "Human",
        "totalCredits": 2.23
      },
      {
        "name": "Droid1",
        "__typename": "Droid",
        "primaryFunction": "Code"
      },
      {
        "name": "Droid2",
        "__typename": "Droid",
        "primaryFunction": "Automate"
      }
    ]
  }
}