> With most web apps having their front-end and back-end developed in concert, there's simply no need for this flexibility
But also no problem with it. There might be some queries expressible in your GraphQL that would have severe performance problems or even bugs, sure, but if your frontend doesn't actually make queries like that, who cares?
> Just have the backend provide the APIs that the front-end actually needs. If those needs change, also change the backend.
Sure, but how are you actually going to do that? You're always going to need some way for the frontend to make requests to the backend that pull in related data, so that you avoid making N+1 backend calls. You're always going to have a bunch of distinct but similar queries that need the same kind of related data, so either you write a generic way to pull in that data or you write the same thing by hand over and over. You can write each endpoint by hand instead of using GraphQL, but it's like writing your own collection datatypes instead of just pulling in an existing library.
> There might be some queries expressible in your GraphQL that would have severe performance problems or even bugs, sure, but if your frontend doesn't actually make queries like that, who cares?
People with bad intentions can make those slow queries happen at high volume with custom tooling, they don’t have to restrict themselves to how the frontend uses the queries
> People with bad intentions can make those slow queries happen at high volume with custom tooling, they don’t have to restrict themselves to how the frontend uses the queries
Depends how your system is set up. I'm used to only allowing compiled queries on production instances, in which case attackers have no way of running a different query that you don't actually use.
Shrug, databases have been doing the same thing since the 1970s (and consider also e.g. regexes). Turns out a flexible, expressive language for writing queries isn't always the most secure or performant thing to use as your wire format.
Do you understand that decompilers and reverse engineering are a thing?
Adversaries are not restricted to using your system the way you designed your system. GraphQL queries are trivial to pull out of Wireshark and other sniffers. If you deliver it to the browser, any determined-enough adversary will have it, period. I wouldn't be surprised in the least if it is already a thing for LLM models to sniff GraphQL endpoints in the quest for ever more data.
> Do you understand that decompilers and reverse engineering are a thing?
Do you understand how compiled queries in GraphQL (or even an old-school RDBMS) work? All that gets sent over the wire is the query id. There's physically no way to make the server execute a query the author didn't write.
So you threw out all the benefits of GraphQL. Instead of allowing the frontend to determine what it needs, you need to write a new backend endpoint that will return what's needed for that page. This is no different from writing some /rpc/bffe/get-profile-page call, which is much simpler to write and has much better tooling.
No, our backend serves all the queries that the frontend uses, but (in prod) only the queries that the frontend uses - we compile the queries at build time. When we want to add a new query we figure it out in dev (which allows non-compiled queries, but is not accessible for people outside the company), write it in the frontend, and it will be included in the next build of the backend. This is all pretty basic off the shelf functionality. Maybe spend 5 minutes trying to think about how a system might work instead of assuming everyone else is an idiot.
Yea so you have to add the compiled queries to your back-end to be able to get them on prod, which is what you came out swinging against with a somewhat strongly worded to level comment berating people who choose to not use graphql for having to deal with. Exactly what you just described doing is what the parent comment expected you were doing.
> Yea so you have to add the compiled queries to your back-end to be able to get them on prod, which is what you came out swinging against with a somewhat strongly worded to level comment berating people who choose to not use graphql for having to deal with.
What are you talking about?
The build process takes the queries the frontend wants to use, compiles them, and includes them in the backend build. There is no manual step, you don't even change a single line of code or config on the backend, much less write a new endpoint. As far as I'm aware this is the completely normal way to use graphql.
I think I finally understand your earlier comment in context:
> You can write each endpoint by hand instead of using GraphQL, but it's like writing your own collection datatypes instead of just pulling in an existing library.
Everyone else is "pulling in an existing library", they have names like Express and Kysely, and thinking that Apollo is the only library that deserves this designation is a bit of a head-scratcher.
If you take the time to invest in a proper REST API first, odds are the endpoint may already exist, and you may not need to wait for a new backend build; not investing in a custom endpoint for every frontend change unless real-world performance requirements actually dictate it. You get tooling that is more mature and easier to maintain as a result, makes it easier for Product to experiment (remember: not forcing a backend change for every frontend change), and not using a fad-of-the-month just because it came out of a FAANG.
> If you take the time to invest in a proper REST API first, odds are the endpoint may already exist, and you may not need to wait for a new backend build; not investing in a custom endpoint for every frontend change unless real-world performance requirements actually dictate it. You get tooling that is more mature and easier to maintain as a result, makes it easier for Product to experiment (remember: not forcing a backend change for every frontend change)
If it's a giant system where your backend/frontend/product teams are separate, maybe - but even then, they can run any custom queries they want on non-prod instances, so it's easy to do internal testing, and always including backend deployment when you do a prod release is not a huge burden.
I still think there's never going to be an advantage to doing N+1 queries - there might be cases where the performance difference doesn't matter, but an endpoint that returns precisely what you want would always be better if you could get it for free. And you can't really set up "aggregating" endpoints ahead of time, unless you pre-emptively create all N*N possible combinations, and that's going to go against having a "clean" normalised set of REST endpoints. Just like in a database schema, there's value in having every individual endpoint orthogonal and then doing the joining at query time, at least for a system under active development where you want to try new things without redoing your whole dataflow.
> not using a fad-of-the-month just because it came out of a FAANG.
I don't think it's a fad at this point - graphQL has been around for 10 years, the systems I've worked on have been using it successfully for about 5, and the design is built on what the likes of Thrift and gRPC were already doing where possible. There are, as you pointed out, multiple library implementations for many languages. It's popular because it works.
Exactly. People pull this argument right out of their hat, already prepared, where spending just a few moments thinking about it would give one pause.
The tools and patterns to limit these (very common, in any kind of system) drawbacks are so well-established that its a non-issue for anyone sincerely looking at the tech.
But also no problem with it. There might be some queries expressible in your GraphQL that would have severe performance problems or even bugs, sure, but if your frontend doesn't actually make queries like that, who cares?
> Just have the backend provide the APIs that the front-end actually needs. If those needs change, also change the backend.
Sure, but how are you actually going to do that? You're always going to need some way for the frontend to make requests to the backend that pull in related data, so that you avoid making N+1 backend calls. You're always going to have a bunch of distinct but similar queries that need the same kind of related data, so either you write a generic way to pull in that data or you write the same thing by hand over and over. You can write each endpoint by hand instead of using GraphQL, but it's like writing your own collection datatypes instead of just pulling in an existing library.