| > simply replacing REST adds resolver complexity [...] To put it simply, even with REST, you're already dealing with the concept of "how does clients get a handle of a particular entity?" With REST, the answer is usually muddled by client data fetching mechanisms and backend architecture that you've opted to use - so just because two projects are doing REST does not mean they're handling these entities in a similar, understandable nature and it requires a lot of background context, same with auth. graphql makes all that a deliberate matter instead. So take whatever's in your db, decide which fields are you going to expose, and write resolvers that return just that - you can't get any more foolproof than that, it's basically the same thing you do with REST, just without all the client-side fumbling and coordination. But what I'd argue the thing it does best, is that with REST, you'd probably write code for handling Entity A, and if Sub-Entity A and B rely on Entity A, you'd probably write specific code to ensure the right entities are returned in your endpoints. With graphql, you just reference that entity and it's resolved automatically, because you have written the resolver for that entity already. Resolvers have access to the parent entity that's referencing it, so if Sub-Entity B has stricter controls in what it should expose, the Entity A's resolver can be written to accommodate that (see directives among other ways for how to scale this better). As for auth, whatever middleware you're already using in your REST endpoints can also be reused one way or another for the gql endpoint, no issue. > this hyper graph thing is only valuable with other graphql services. Even without other graphql consumers/services, there's huge value in not having to write multiple ways of handling a certain entity anymore, among other things. > So, I guess graphql can be good if you marry it and go 100% all in? All of my recent work related to graphql happened in projects that incrementally adopt it - there's no requirement whatsoever to fully commit to it 100%. It definitely helps that you can reuse whatever your REST endpoints use to comprise code that builds up towards resolvers, like util/helper fns. Nothing stops you from serving the same entity in both REST and graphql forms, heck there's specific usecases that benefit from it (i.e. maybe your mobile app can't keep up with it yet, and you're trying it out for web for now etc) Say, in such kinds of projects, what I can recommend is identifying a subset of entities that your backend serves that you think (at least superficially) will benefit from it e.g. a relatively new entity that is essentially WIP across releases, and you'd benefit from at least not having to redo the entire REST API endpoint subset for this entity whenever you're making drastic changes, or a particularly old one that could use a rethinking anyway, among other use cases. After a couple of releases you'll get a feel for how it works, and then it'll be enjoyable to port more of the entities later on. |
> decide which fields are you going to expose, and write resolvers that return just that
To be clear this means writing custom resolvers? That seems like the most sane way to use graphql, should I ever revisit it.
What’s the logical authorization entity? In rest, it’s (typically) the endpoint itself. What is it in graphql? Does a specific entity resolver have authorization? What does it look like in pseudocode?
How hard is it to write custom resolvers that also produce efficient sql? A gql query can be arbitrarily complex (ie nested), no? How to curb that complexity in practice?