4 ms·
I'm probably about as qualified to talk about GraphQL as anyone on the internet: I started using it in late 2016, back when Apollo was just an alternate client-
by gavinray 10mo ago
I'm probably about as qualified to talk about GraphQL as anyone on the internet: I started using it in late 2016, back when Apollo was just an alternate client-side state/store library.
The internet at large seems to have a fundamental misunderstanding about what GraphQL is/is not.
Put simply: GQL is an RPC spec that is essentially implemented as a Dict/Key-Value Map on the server, of the form: "Action(Args) -> ResultType"
In a REST API you might have
app.GET("/user", getUser)
app.POST("/user", createUser)
In GraphQL, you have a "resolvers" map, like:
{
"getUser": getUser,
"createUser": createUser,
}
And instead of sending a GET /user request, you send a GET /query with "getUser" as your server action.
The arguments and output shape of your API routes are typed, like in OpenAPI/OData/gRPC.
That's all GraphQL is.
- 8n4vidtmkvmk 10mo agoI think you're oversimplifying it. You've left on the part where the client can specify which fields they want.
- verdverm 10mo agoThat's something you should only really do in development, and then cement for production. Having open queries where an attacker can find interesting resolver interactions in production is asking for trouble
- hdjrudni 10mo agoSure, maybe you compile away the query for production but the server still needs to handle all the permutations.
- verdverm 10mo agoyup, and while they are fixed, it amounts to a more complicated code flow to reason about compared to you're typical REST handler Seriously though, you can pretty much map GraphQL queries and resolvers onto JSONSchema and functions however you like. Resolvers are conceptually close to calling a function in a REST handler with more overhead I suspect the companies that see ROI from GraphQL would have found it with many other options, and it was more likely about rolling out a standard way of doing things
- fgkramer 10mo agoBut has this been thoroughly documented and are there solid libraries to achieve this? My understanding is that this is not part of the spec and that the only way to achieve this is to sign/hash documents on clients and server to check for correctness
- verdverm 10mo agoWell, it seems that the Apollo way of doing it now, via their paid GraphOS, is backwards of what I learned 8 years ago (there is always more than one way to do things in CS). At build time, the server generates a random string resolver names that map onto queries, 1-1, fixed, because we know exactly what we need when we are shipping to production. Clients can only call those random strings with some parameters, the graph is now locked down and the production server only responds to the random string resolver names Flexibility in dev, restricted in prod
- girvo 10mo agoI mean yeah, in that Persisted Queries are absolutely documented and expected in production on the Relay side, and you’re a hop skip and jump away from disallowing arbitrary queries at that point if you want to Though you still don’t need to and shouldn’t. Better to use the well defined tools to gate max depth/complexity.
- verdverm 10mo agoAll these extra requirements are why GraphQL never really captured enough mindshare to be a commonly selected tool
- girvo 10mo ago> GraphQL never really captured enough mindshare to be a commonly selected tool It has been, at the scale it matters and should be used at. Most companies don't operate at that scale though.
- Aurornis 10mo ago> That's something you should only really do in development, and then cement for production My experience with GraphQL in a nutshell: A lot of effort and complexity to support open ended queries which we then immediately disallow and replace with a fixed set of queries that could have been written as their own endpoints.
- twodave 10mo agoThis is not the intended workflow. It is meant to be dynamic in nature.
- jayd16 10mo agoThis seems a bit reductive as it skims over the whole query resolution part entirely.
- ericyd 10mo agoIs this relevant to the posted article? I don't see how the OP misrepresents anything about GQL.
- mirekrusin 10mo agoExcept you can't have ie. union as argument, which means you can't construct ie. SQL/MongoDB-like where clauses.
- rbalicki 10mo agoThis is a genuinely accurate critique of GraphQL. We're missing some extremely table-stakes things, like generics, discriminated unions in inputs (and in particular, discriminated unions you can discriminate and use later in the query as one of the variants), closed unions, etc.
- andrewingram 10mo agoAs someone who’s used GraphQL since mid-2015, if you haven’t used GraphQL with Relay you probably haven’t experienced GraphQL in a way that truly exploits its strengths. I say probably because in the last ~year Apollo shipped functionality (fragment masking) that brings it closer. I stand by my oft-repeated statement that I don’t use Relay because I need a React GraphQL client, I use GraphQL because I really want to use Relay. The irony is that I have a lot of grievances about Relay, it’s just that even with 10 years of alternatives, I still keep coming back to it.
- maxcan 10mo agoCan you elaborate? I've used URQL and Apollo with graphql code gen for type safety and am a big fan. What about relay is so compelling for you? I'm not disagreeing, just genuinely curious since I've never really used it.
- tcoff91 10mo agoTry gql tada it’s much better than graphQL codegen
- maxcan 10mo agoI did. I really wanted to like it. I think it broke due to something I was doing with fragments or splitting up code in my monorepo. I may give it a shot again, from first principles it is a better approach.
- andrewingram 10mo agoFor me it’s really about the component-level experience. * Relatively fine-grained re-rendering out of the box because you don’t pass the entire query response down the tree. useFragment is akin to a redux selector * Plays nicely with suspense and the defer fragment, deferring a component subtree is very intuitive * mutation updaters defined inline rather than in centralised config. This ended up being more important than expected, but having lived the reality of global cache config with our existing urql setup at my current job, I’m convinced the Relay approach is better. * Useful helpers for pagination, refetchable fragments, etc * No massive up-front representation of the entire schema needed to make the cache work properly. Each query/fragment has its own codegenned file that contains all the information needed to write to the cache efficiently. But because they’re distributed across the codebase, it plays well with bundle size for individual screens. * Guardrails against reuse of fragments thanks to the eslint plugin. Fragments are written to define the data contract for individual components or functions, so there’s no need to share them around. Our existing urql codebase has a lot of “god fragments” which are very incredibly painful to work with. Recent versions of Apollo have some of these things, but only Relay has the full suite. It’s really about trying to get the exact data a component needs with as little performance overhead as possible. It’s not perfect — it has some quite esoteric advanced parts and the documentation still sucks, but I haven’t yet found anything better. Did my only ever podcast appearance about it a few years ago. Haven’t watched it myself because yikes, but people say it was pretty good https://youtu.be/aX60SmygzhY?si=J8rQF6Pe5RGdX1r8 https://youtu.be/aX60SmygzhY?si=J8rQF6Pe5RGdX1r8
- scotty79 10mo agoGraphQL is best if the entire React page gathers all requirement from subcomponents into one large GraphQL query and the backend converts the query to a single large SQL query that requests all the data directly from database where table and row level security make sure no private data is exposed. Then the backend converts SQL result into GraphQL response and React distributes the received data across subcomponents. Resolvers should be an exception for the data that can't come directly from the database, not the backbone of the system.
- nromito 10mo agoThis is a great explanation of what the intent of GQL is. I'm curious though, as someone who has only a small amount of experience with it, what problem is that solving? From what I can tell, it's the same problem REST solves with a different interface. If it is the over-fetching problem, how big is that problem? In my experience, it's better to fix a bad endpoint and keep all the browser/server side tooling around tracing requests than to replace all that with a singular graphql endpoint. But curious to hear someone else's opinion here