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
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
Top comments (2)
Worked like a charm! Thanks for this.
Glad it helped :)