loading...

How to use GraphQL Fragments with Apollo

darksmile92 profile image Robin Kretzschmar ・2 min read

GraphQL requires that the queries specify the fields to return with the result to prevent over-selecting (too much fields) by design.

This means for us developers that if we design a GraphQL query, we need to write out all the fields we want to retrieve from the query node.

GraphQL itself has a really nice concept called Fragments to make life easier:

GraphQL includes reusable units called fragments. Fragments let you construct sets of fields, and then include them in queries where you need to.

This is great to use on the server side.

Here is how it looks on the server side (copied from the docs):

{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}

You can also use Fragments with Apollo on the client side!

Why? To have as less as possible lines to change when a new field is added on a type and needs to be returned! ... and of course to type the fields only once :-D

GIF of fast typing

The apollo client lets you define queries in the following syntax:

// gqlQueries.js
import gql from 'graphql-tag';

export const MY_CONTENT_QUERY = gql`
  query MY_CONTENT_QUERY($id: ID!) {
    contentDetails(id: $id) {
      id
      contentUpdated
      title
      body
      notes
      link
      tags {
        id
        name
      }
      updatedAt
    }
  }
`;

We are already using the graphql-tag library here, so we can also use it to construct Fragments!

This example defines fragments in a separate file, imports them into the file where the queries are defined and uses them.

// gqlFragments.js
import gql from 'graphql-tag';

export const FRAGMENT_CONTENT_ALL_FIELDS = gql`
    fragment ContentAllFields on Content {
        id
        contentUpdated
        title
        body
        notes
        link
        tags {
            id
            name
        }
        updatedAt
    }
`;

// gqlQueries.js
import gql from 'graphql-tag';
import { FRAGMENT_CONTENT_ALL_FIELDS } from './gqlFragments';

export const MY_CONTENT_QUERY = gql`
  query MY_CONTENT_QUERY($id: ID!) {
    contentDetails(id: $id) {
      ...ContentAllFields
    }
  }
  ${FRAGMENT_CONTENT_ALL_FIELDS}
`;

My personal preferences:

Use Fragments if:

  • you query the same set of fields of a type more than once
  • you query fields of a type from which you know it could get more fields in the future that also needs to be returned
  • you refactor an existing query and add a field to it

Don't use Fragments if:

  • you are writing a PoC
  • you have less than 3 queries for a type
  • you don't always have the same fields for each query for a type

Posted on by:

darksmile92 profile

Robin Kretzschmar

@darksmile92

Started coding at the age of 13, now a professional software engineer creating and maintaining enterprise solutions. Eat - Sleep - Code - Lift - Repeat 💪🏾

Discussion

pic
Editor guide