HACKER Q&A
📣 johnmaguire

GraphQL users for single-page applications, what are your experiencies?


If you're implementing GraphQL on the backend or querying a GraphQL API for data on the frontend of a reactive single-page application, what's your overall impression of it?

Has the extra complexity been worth it over building a RESTful or RESTless (e.g. RPC) API?

The strong typing on the client and server, well-defined protocol with introspection built-in, and flexibility of the query language seem like a boon for quick frontend development.

However, it seems to come with some complexities - reworking middleware into something compatible with resolvers (authentication, rate limiting, etc.), concerns about queries being used in ways you don't expect (N+1 problems, solvable via data loaders or query complexity limits), and common methods for viewing metrics (e.g. tracking stats by URI, status code, and verb) need to be reconsidered.

How's it working out for you?


  👤 vaughan Accepted Answer ✓
The big draw for me was the built-in introspection. E.g. https://docs.github.com/en/graphql/overview/explorer. An awesome way to access third-party apis.

I can see it being useful at large organizations with many services written in different languages with many distinct teams. But then there is of course performance concerns from giving users so much flexibility, versus offering more limited REST/RPC APIs with more predictable performance.

But for your own APIs where your frontend and backend are tightly coupled, it just gets in the way and is too verbose. You often don't want a big nested response, but rather a flat, normalized response for caching. The JSON:API standard is much more ideal in this regard. Mutations and optimistic UI updates are incredibly painful. Look at this craziness: https://www.apollographql.com/docs/react/performance/optimis.... Most client implementations do not maintain any concept of the underlying relations between the data they return either which makes caching difficult. Code generation of types is annoying to have to run as a separate process, and doesn't result in the best experience. Writing out all the fields you need for every query in full is too verbose and most people don't need to limit the number of fields they need returned, and then hacks like using Fragments feel messy. Writing schemas is painful too. You have to jump through hoops if you want to just return a JSON object.

Also, Apollo was a terrible client with really bad error messages for so long and never seemed to fix things. The caching and optimistic UI updates are terrible as mentioned too. Urql seemed to do the caching a lot better, but it feels like huge amounts of code to patch over a leaky abstraction, just like most ORMs.

In the short-term I would suggest trying out something like trpc.io. It's like the feeling of going from Java to Python again.

My general attitude is that your API should stay as close as possible to your backend data model, otherwise caching and optimistic UI updates become really tricky as you end up with all this mapping code. GQL is forcing a graph structure over a relational data model which doesn't fit.

Keep it simple. Request/response. Then see what you need on top of that.