16 ms·
Worked on two GraphQL projects; I was quickly cured from the hype. I recognize a lot of points in this article. In both these projects the GraphQL had started
by atsjie 2y ago
Worked on two GraphQL projects; I was quickly cured from the hype. I recognize a lot of points in this article.
In both these projects the GraphQL had started small. I came in during a more mature phase of these projects (2 and 4 years). That's where the requirements are harder, more specific, and overall complexity has grown. Adoption and demand on the API were growing quickly. Hence you logically spend more time debugging, this is true for any codebase.
But GraphQL has everything in it to make such problems even harder. And both these projects had clear signs of "learning-on-the-go" with loads of bad practices (especially for the N+1 problem). Issue descriptions were much vaguer, harder to find in logs and performance issues popped up in the most random places (code that had been running and untouched for ages).
Fun fact; in both these projects the original devs who set it up were no longer involved. Probably spreading their evangalism further elsewhere.
RPC and REST are just more straightforward to monitor, log, cache, authorize and debug.
- DanielHB 2y agoGraphQL is very good for places where frontend and backend developers are isolated from each other (separate teams). Or rather places where you have data-producers and data-consumers as separate teams. If you have a big enough org eventually there will be many of such teams, interdisciplinary teams are not feasible at scale for everything. It allows teams to work with less communication overhead. It solves more of a human problems than a technical problems, if someone think there is no value in that and bare metal performance is paramount that person never worked in a big org. > RPC and REST are just more straightforward to monitor, log, cache, authorize and debug. In some ways yes, in others no. For example it can be near impossible to see if a deprecated field in a REST API is still being used and by which clients it is being used. With GraphQL this is fairly simple. Unfortunately GraphQL way of working is very different from normal REST APIs and often requires more complex server-side caching. The N+1 problem needs to be figured out upfront for every data-storage system used in the backend.
- dudeinjapan 2y agoCouldn't disagree more. GraphQL encourages tight-coupling--the Frontend is allowed to send any possible query to the Backend, and the Backend needs to accommodate all possible permutations indefinitely and with good performance. This leads to far more fingerpointing/inefficiency in the log run, despite whatever illusion of short-term expediency it creates. It is far better for the Backend to provide Frontend a contract--can do it with OpenAPI/Swagger--here are the endpoints, here are the allowed parameters, here is the response you will get--and we will make sure this narrowly defined scope works 100% of the time!
- beeboobaa3 2y agoNot to mention the fact that GraphQL allows anyone messing with your API to also execute any query they want. Then you start getting into query whitelisting which adds a lot of complexity.
- RHSeeger 2y agoCan you explain what you mean by this? The GraphQL API you expose allows only a certain schema. Sure, callers can craft a request that is slow because it's asking for too much, but - Each individual thing available in the request should be no less timely to handle than it would via any other api - Combining too many things together in a single call isn't a failing of the GraphQL endpoint, it's a failing of the caller; the same way it would be if they made multiple REST calls Do you have an example of a call to a GraphQL API that would be a problem, that wouldn't be using some other approach?
- deleted 2y ago[deleted]
- serpix 2y agoThen we just come back full round trip to REST where the backend clearly defines what is allowed and what is returned. So using GraphQL it is unnecessary complicated to safeguard against a caller querying for all of the data and then some. For example the caller queries nested structures ad infinitum possibly even triggering a recursive loop that wakes up somebody at 3am.
- afiori 2y ago> In some ways yes, in others no. For example it can be near impossible to see if a deprecated field in a REST API is still being used and by which clients it is being used. With GraphQL this is fairly simple. You should log deprecation warnings. But also if the client is composing urls/params manually then you are not doing REST, you are doing RPC. Rest APIs should mainly use HATEOAS hyperlinks to obtain a resource. that is clients almost always call links you have provided in other reponses (starting from a main entrypoint)
- BiteCode_dev 2y agoThe problem is you delegate a lot of the query building to the client, hoping that it will not suddenly change your performance profile by being creative and that you will have not missed an obviously expensive use case coming. That's a huge bet, especially given that GraphQL is expensive in the first place, and given that the more you grow the API in size, the less you can actually map the cartesian product of all request params.
- tomrod 2y agoI haven't done much more than toy projects in GraphQL. Is there no way to limit the query complexity/cost? Such as a statement timeout in postgres?
- BiteCode_dev 2y agoAh but that's the beauty of GraphQL, a query can actually fetch data from several systems: the db, the cache, the search engine, etc. It's all abstracted away. But let's say you have a timeout, and they have a retry, then suddenly, your server is now spammed by all the clients retry again and again a query that worked a week ago, but today is too heavy because of a tiny change nobody noticed. And even if it's not the case, you can now break the client at any time because they decide to use a feature you gave them, but that you actually can't deal with right now.
- barrkel 2y agoTo be clear, the main thing that's abstracted away are server round-trips and client-side joins. REST APIs can fetch data from different systems too.
- BiteCode_dev 2y agoSure but queries are crafted in the client, that may know nothing about this, while a rest api, the requests are restricted and the queries are more likely under control of the server, which mean the backend will likely decide what fetches what and when. It takes a lot of work to actually ensure all possible combinations of graphql params hit exactly what you want in the backend, and it's easy to mess with it in the frontend.
- tuan 2y ago> GraphQL is very good for places where frontend and backend developers are isolated from each other (separate teams) What do you mean by "backend developer" ? The one who creates the GraphQL endpoints for UI to consume ?
- pavel_lishin 2y agoWe have similar issues in our codebases - but not just in GraphQL, but also in our PHP and Elixir code, and to some extent our Typescript stuff. I think the "learning-on-the-go" symptom, where you can sometimes literally read down a file and watch some developer learn the language as they add more and more functions to the file with a gradual increase in skill (or, to put it less charitably, as they slowly get less bad at writing code) is probably a very common thing, and not just a GraphQL issue.
- mattbrewsbytes 2y ago> RPC and REST are just more straightforward to monitor, log, cache, authorize and debug. REST API's are a proven solution for the problem of other apps, including front-ends, needing data from a data store. Using JSON is much improved over the days of XML and SOAP. Beyond that there haven't been advancements in technology that cause fundamental shifts in that problem space. There have been different opinions about structuring REST calls but those aren't going to cause any real forward progress for the industry and are inconsequential when it comes to business outcomes. There are so many developers out there that can't stand plugging in proven solutions to problems and just dealing with the trade-offs or minor inconveniences. Nothing is going to be perfect and most likely a lot of the software we write will cease to be running in a decade.
- aaronbrethorst 2y agoHarder to get a promotion when you’re doing something that’s old, boring, and just works.
- hansonkd 2y agoREST APIS suck for nested resources. GraphQL is a huge breakthrough in managing them. Ever seen an engineer do a loop and make n+1 REST calls for resources? It happens more often then you think because they don't want to have to create a backend ticket to add related resources to a call. With internal REST for companies I have seen so many single page specific endpoints. Gross. > There have been different opinions about structuring REST calls but those aren't going to cause any real forward progress for the industry and are inconsequential when it comes to business outcomes. You could argue almost any tech solution in a non-pure tech play is largely in consequentially as long as the end goal of the org is met, but managing REST APIS were a huge point of friction at past companies. Either it goes through a long review process to make sure things are structured "right" (ie lots of opinions that nobody can sync on) or people just throw up rest endpoints willynilly until you have no idea what to use. GraphQL is essentially the "Black" for Python Syntax but for Web APIs. Ever seen engineers fight over spaces vs tabs, 8 vs 4 spaces, whether a space before a colon? those fights happened a lot and then `black` came out and standardized it so there was nothing to fight over. GraphqL makes things very clear and standard, but can't please everyone.
- flashgordon 2y ago>> Fun fact; in both these projects the original devs who set it up were no longer involved. Probably spreading their evangalism further elsewhere. Ah this brings up bitter memories. Team I was managing was roped in to become the first graphql framework (nay platform) the ivory tower (central architecture run by the cto) team was building and trying to shove down the rest of the company. This was during the graphql craze around 5 years ago. The principal engineer leading it was even preemptively promoted to distinguished engineer for future contributions. Fast-forward 5 years project was disbanded due to massive migration, cost and complexity problems. DE still lauded for experimentation heroism and evangelism. I think he is now pushing the latest flavors of the month to go for the next promo!
- canadiantim 2y agoNow where does Braid-HTTP fit in?!
- bryanrasmussen 2y ago>And both these projects had clear signs of "learning-on-the-go" with loads of bad practices I think two projects having loads of bad practices is too small a dataset to really assume anything, you sort of need to see widespread "bad practices" in the tech to be able to determine that the bad practice is actually the norm practice and there is perhaps a flaw in the tech that encourages that norm.
- arp242 2y agoYou're not wrong, but at the same time I think it's a decent data point that getting it right is not straight-forward and that, practical speaking, you at the very least need to think very carefully before actually using it. "The idea of it" is sometimes fine, but then there's also "the practicality of it", and sometimes that's a very different thing. Remember the old microkernel vs. monolithic debate; everyone more or less agrees that in principle, a microkernel is better. But the practicality of it is a lot more complex, so monolithic kernels and hybrid ones are much more common. Microservices vs monolithic is essentially the same debate, and I've seen a lot of Microservices with very poor implementations and a lot of problems. That doesn't mean the idea is bad in itself, but if it's hard to execute well, then you do need to be very careful. There's tons more examples of this. You also see this sort of thing in e.g. politics, where what's "more fair" vs. "what's actually achievable without introducing heaps of bureaucracy and overhead" are sometimes very different things. In the case of GraphQL, I think it's pretty obvious that the general idea, as described from a high level, is a good one. But the practicalities of it are a lot less straight-forward, as this article explains reasonably well IMHO.
- bryanrasmussen 2y agoI think one of the issues is actually that GraphQL has no specific implementation, it's not like you have an SQL database and that's it, so one thing is that when you are consuming a GraphQL api it is impractical for various implementation related reasons from the vendor. With GraphQL you are doing a lot of extra work query wise than you do with REST, which is supposed to translate into various benefits. But each vendor has different implementation details that affects whether you actually receive those benefits. This is different than REST, the benefits of REST are generally the same for every vendor because implementation details and API are extremely simple, what is different is the data structure you receive back. In GraphQL both the data structure and the implementation details are different. GraphQL I think doesn't make sense if you have multiple data sources from different vendors, because of this increase in complexity and not being to trust how good their implementation actually is until you've gotten into it.
- hinkley 2y agoI knew we were in trouble when we started having to sort the query criteria in order to support caching of requests. If I use graphQL again it’ll only be for admin features. Anything where very few users will use it and very infrequently. Preferably in spots where caching works against the workflow. OLAP vs OLTP. GraphQL is really about reducing friction between teams. High functioning distributed systems all have two qualities in common: work stealing and back pressure. Without back pressure there is nothing to stop the project from running off a cliff.
- esafak 2y agowhat's work stealing?
- hinkley 2y agoIt’s when you can reassign a task earmarked for one machine to another after the fact. There’s a latency and throughput problem to keeping all tasks on a central server until a worker finishes an existing task. But if you locally queue, and one worker gets unlucky and gets the longest tasks, then the whole cluster sits idle while this worker starts and finishes multiple tasks. If you reallocate the ones that haven’t started or have timed out, then the overall time comes down quite a bit (and in the latter case also covers workers that crash). For development teams it could mean moving the boundary on a service or API so your team does more of the feature work than originally planned, because the other team keeps getting jammed up on bugs or other operational issues.
- taeric 2y agoThat fun fact bothers me at a fundamental level. I've seen it happen so many times and is really painful when the people were promoted out of the place. Even worse when they are good developers, but often in a cowboy style where they confuse their energy for some fundamental efficiency of what they were doing.