Apollo

Apollo is the dominant client tooling for GraphQL. Apollo Client is the part that matters on the frontend, and calling it an HTTP wrapper undersells it — it becomes the application’s data layer.

The reason it exists is that raw GraphQL over HTTP is unpleasant to use directly. Sending a query and receiving JSON is trivial; the difficulty is everything after: caching results so the same data is not refetched, keeping views consistent when one mutation changes an entity several components display, and handling loading and error states without duplicating the logic everywhere.

The normalised cache

Apollo’s central feature is a cache keyed by entity identity rather than by query. Results are decomposed into individual objects stored by type and ID, so a user fetched as part of one query and as part of another is one cache entry.

The payoff is real: mutate that user, and every component displaying it updates, with no manual invalidation and no subscription plumbing. This is the thing that makes GraphQL feel worthwhile, and it is genuinely hard to replicate with an ad-hoc REST client.

The cost is that the cache is a stateful system with its own semantics. Entities without a stable ID need explicit key configuration or they are cached wrongly. Lists do not update automatically when an item is added, because Apollo cannot know which lists a new entity belongs to — that requires manual cache updates, and it is the single most common source of confusion. Pagination needs field policies describing how pages merge.

None of that is unreasonable, and all of it is work that does not appear in the tutorial.

When it is worth it

It is worth it when the application genuinely benefits from client-driven queries and shared entity state across many views. It is not worth it when the data model is simple and predictable, where a generated REST client gives type safety with a fraction of the machinery and no cache semantics to learn.

The honest comparison is not Apollo against a raw fetch call. It is GraphQL-plus-Apollo against REST-plus-generated-client — and framed that way, the answer depends on whether clients need to shape their own queries, which is the same question the REST versus GraphQL comparison turns on.

See also: GraphQL, Vue 3, APIs, and OpenAPI client generation for the REST-side equivalent.