Hacker News new | ask | show | jobs
by lilactown 1949 days ago
If you do a survey of front end data fetching frameworks, they basically land in two categories:

- API-agnostic: react-query, rtk-query, swr

- Declarative queries (e.g. GraphQL): apollo-client, relay, urql

A major difference to notice is that the API-agnostic libraries do not handle normalizing the data before caching it. Instead, they cache the data based on some key related to the request. So you can potentially fetch and cache two different versions of the (semantically) same information, leading to UI incoherence. The various API-agnostic libraries have ways of solving this by explicitly creating relationships between different requests so that you can manually say, "when I fetch with this key, also trigger a re-fetch of any components subscribed to these other cache keys." This is coarse, but for many cases "good enough" in contexts where you don't have full control over the API you are fetching data from.

In order to leverage a normalized cache, the layer between the cache and network needs to intimately understand what data is returned by which request so that it can support things like stale-while-revalidating, re-rendering on refetch of the same data from another part of the page, etc. Describing all of the data that could possibly be returned by an endpoint is tedious and error prone, as APIs can be dynamic in what they return and backend changes could easily lead to breaking any assumptions the frontend might make about an opaque endpoint.

Now if you have more control over how a backend behaves and buy-in on solving this problem full stack, you can start to build some of these assumptions into both layers. For instance, you could require all endpoints to be fully documented via swagger, and the front end could use the swagger JSON doc to map endpoints to data potentially returned by a response. You would also need a pattern to key each request with what entity (type + ID) it is responding data with before it completes; HATEOAS provides a standard of relating URIs to entities and would solve this problem.

So you can see that this normalized caching problem can be solved without GraphQL, as long as the backend and frontend can agree on a set of standards and requirements such as REST + HATEOAS + Swagger. Personally, if someone is passionate about solving this problem, I would recommend GraphQL, but it is up to each team to decide on what solutions meet their requirements.