A large part of GraphQL is the idea of tightly coupling queries to code, declaratively, combined with smart differential logic.
The original web framework for GraphQL was Facebook's Relay, which essentially lets you declare, in your component, what data you want. Relay stitches together your query and avoids work by figuring out the difference between what data the client has (in its cache) and hasn't.
Apollo's React framework is based around the same ideas. You're supposed to declare the query privately in the component that needs it, and in principle, caching should avoid many unnecessary fetches. For example, if you have:
// In component A
{
currentUser { id, name }
topStories { id, title }
}
// In component B
{
currentUser { name }
favouriteTopics { id, name }
}
then the delta from A to B is { favouriteTopics { id, name } }, and no re-fetching of currentUser is needed, since it is a subset that merely needs to be filtered.
(There are of course ways to write queries that will always conflict with each other, e.g. by applying different parameters such as filters to nested fields.)
In practice, I'm not sure if Apollo is that smart yet. I think it currently considers any difference in field selections to be a conflicting change, even strict subsets, but I could be wrong.
When used outside of React, GraphQL becomes more like SQL:
for (const {name} of (await query(gql`{
users { id, name }
}`)).users {
// ...
}