Skeptical GraphQL quotes
ulkesh: We’re in a java backend and GraphQL in Java with ORM is considerably problematic when trying to create efficient resolvers. We simply ran into one hurdle after another and we were finding ourselves in diminishing returns. Ask HN: Were you happy moving your API from REST to GraphQL? (2018)
lewisl9029: Client UX is king for a large majority of user facing applications. And that's where client-centric query mechanisms like GraphQL/Falcor/Om.next make the most sense.
The point is exactly to
push data fetching complexity from the Client to the API server. And that's generally a worthwhile tradeoff for these applications because you can deal with server complexity by throwing more money at your API server cluster, but you can't force your users to upgrade to more performant clients.
server-side overfetching is a problem that can drastically limit the scalability of your system by overloading the components you can't as easily scale by spinning up more machines(i.e. most databases).
Naive implementations of GraphQL on the server can be ridiculously chatty and require multiple server-db roundtrips to resolve even the simplest of queries, which can arguably be an even nastier problem than dealing with multiple client-server roundtrips with a RESTful API.
This is why non-trivial GraphQL servers generally use some kind of resolver batching/caching layer (Facebook provides a library called DataLoader to facilitate this: https://github.com/facebook/dataloader) or a query planner at your root resolver (like Join Monster: https://github.com/stems/join-monster).
Neither of these approaches is trivial to implement, but then again, doing efficient data fetching on the client against a RESTful API is just as difficult, if not more so. Efficient data-fetching is just a very difficult problem, and involves essential complexity that needs to live somewhere. At the end of the day it's up to you if you want to deal with that complexity in your clients (using a traditional RESTful API) or on your API servers (using a query mechanism like GraphQL).
solidsnack9000 on HN (2017)
At Facebook, GraphQL is used in a such a way that all queries are predeclared -- developers write a collection of queries that represent their client's interface to the backend, and only these queries are used in the live app. This has two positive effects:
- It's fairly easy to tell "how the app is using the database" -- queries are not dynamically generated or hidden in code.
- The query performance is predictable and controllable in the same way as a stored procedure approach to database access -- but without actually requiring a DBA to load/unload procedure definitions.
One might argue that these benefits could be obtained without codifying a new query language...but when you start to think about nested objectsyou start to warm up to the idea.
KirinDave on HN (2017)
So let's take the most trivial case. Pretend you can query a Person object with both familyName and personalName. A single GQL query resolver must be able to recognize which field you want and ideally construct the minimum query that meets the requirements. This is much harder than simply recognizing the correct parameters out of the URL, body and queryParams and execute it.
While the stakes are low for overfetching – in this case odds are the DB doesn't notice and maybe it's not a problem for your network link – as a general problem – in particular when fields have subfields – this gets frustrating very quickly.
My concern is not that this is bad for clients. It makes a ton of sense for clients. It's just much harder for servers to schedule optimal queries. Suddenly you're not only managing unreliable resources and minimizing latencies you don't own, you're also a compiler or interpreter for a language with more than one valid query.
For some types of backing stores it may not matter (ECKRV's such as Dynamo, for example). For others it may matter a lot (Postgres). And I think a lot of server owners ship backends that maybe do 2x more querying than they have to, given the "best practices" and examples I see online for the NodeJs bindings.
I've heard the Erlang bindings are very good. I haven't tried them yet, as Erlang isn't very high on my list of tools to use these days (not because it's bad). Maybe they have a silver bullet.
deegles 30 days ago [-] I think you answered your own question... GraphQL and similar are meant to push complexity to the endpoint partly in order to not tax resource-constrained clients. If that's part of your requirements then it's a great fit, otherwise your points are valid.
KirinDave 30 days ago [-] In a more perfect world, it'd make sense. Mutations in particular make lots of sense because it narrows the scope of any required transactional semantics. But the fact that I've only seen one implementation correctly implement the query semantics worries me deeply. At first I assumed I was using bad libraries! But soon I realized that lots of devs were simply shipping significantly less efficient servers to production.
intellix 30 days ago [-] I like to think of it like this: If you over fetch, you throw it away at the server and not after sending it to the client. You can wrap a standard REST API and it'll still be more optimal. We've been using REST and slowly adding hacks to stop sending so much data. We have 2x API calls that used to be 1mb each and now they're something like 5kb with GQL.
KirinDave 30 days ago [-]
one of the practical benefits is that multiple queries from client to server can be merged into one, thus saving bandwidth and improving performance. Sure, but if we're doing that by dragging the API implementer over every possible permutation of queries, optimizing whatever you could possibly ask for, I'm not convinced this is LESS work than me shipping BTO API requests. I'm sure certain types of projects will benefit more from the pros than cons of GraphQL. My sneaking suspicion is that it's the kind of projects where their data model is small and isolated and doesn't offer much sharing between queries. Which is great when you can get it.
swlkr 30 days ago [-] In my limited experience implementing a GraphQL server with node.js at work for a smaller app, it adds quite a bit of complexity to getting data out of a relational database. After implementing GQL, I found this very old slide show on REST and it happened to solve my complexity problems. https://www.slideshare.net/mobile/landlessness/teach-a-dog-t... GQL and this alternative have their place and they solve problems for very large teams of (like the teams at Facebook), but for smaller teams and smaller apps, I'm not sure it's the right solution to REST's "join" problem.
alvis: As a GraphQL user, hardly I can say it is perfect, but it does solve many current challenges arisen from the surge of mobile use, namely the waste of bandwidth on headers and unused content, as well as latency between requests. http2 has arrived. With http2, the biggest selling point of reducing latency by using one single endpoint does not sound anymore.
- [DUSTIN: This is not too insightful as http2 doesn’t solve dependent requests]