When building apps, we often show post summaries (title, excerpt) in listing pages, and show full author info on the detailed post view. If you're fetching everything (including the author info) all the time, you're overfetching.
One of the key benefits of GraphQL is the ability to avoid this. Frontend receive only the data that they requested.
For example, This query fetches author info for all posts:
const fetchPostsDocument = gql`
query fetchPosts {
posts {
title
content
author {
name
}
}
}
`;
Here, we're fetching the author field for every post, even if we're just rendering a summary list where that information isn't needed.
That means:
- The backend has to make an extra query to get required author data.
- Your network payload is bigger.
- Your query is slower, unnecessarily.
Which can be avoided by using @include
directive to conditionally fetch fields
we need:
const fetchPostsDocument = gql`
query fetchPosts($includeAuthor: Boolean!) {
posts {
title
content
author @include(if: $includeAuthor) {
name
}
}
}
`;
If you're using graffle, here's how you can call it:
// When rendering summary list
client.request(fetchPostsDocument, { includeAuthor: false });
// When rendering detailed post view
client.request(fetchPostsDocument, { includeAuthor: true });
By using the includeAuthor
directive, you can reuse the same query for both
the summary list and the detailed post view. Instead of creating separate
queries for each use case, now we can just simply toggle the includeAuthor
variable.
If you're using GraphQL Codegen, You might be wondering how GraphQL Codegen handles type safety when the author field is fetched conditionally.
The answer is, it marks author as an optional field in the generated TypeScript types.
export type FetchPostsQuery = {
posts: {
title: string;
content: string;
author?: {
name: string;
};
}[];
};
That means even if you know includeAuthor is true
, you'll still need to use
optional chaining (post.author?.name
) to access the author's name.
That's it. With a small change, you avoid overfetching, make your app faster!.