As far as I understand hardcover was really created because goodreads discontinued their api and the team at hardcover saw how many people relied on it for a myriad of different niche projects.
If hardcover was just a replacement for the goodreads platform, then I'd agree with you. But it's not. It's there for the api, with the platform around it intended as a way to ensure free access of the api for everyone. And from that pov choosing GraphQL makes a lot of sense imo. You can't anticipate all the cool and different things people might want to do with it, so they chose the most flexible api spec they could.
On the other hand, I'm not sure if a complete rails rewrite was the right choice. The App was slow and sluggish beforehand, with frequent ui glitches and it still has those same issues. Their dev blog claims significant performance increases, but as a user I haven't noticed a big difference. Sticking with next.js, but moving to a selfhosted instance and then iteratively working on performance improvements would've been (imho) the better way forward. I see no reason why next.js somehow fundamentally couldn't do what they're trying to do, but rails can. Especially with just 30k users (which tbc is a great achievement, just not impressive from a technical standpoint).
Do you need a separate frontend framework? No, probably not, and that's exactly the problem that Next solves - write your backend and frontend in the same place.
Do you need a complicated build process? No. You want your build process to be just "run npm". And that's what something like Next gets you.
"Monolithic RoR app with HTML templates on VPS" would introduce more problems than it solves. If Next-style frameworks had come first, you would be posting about how RoR is a solution in search of a problem that solves nothing and just overcomplicates everything. And you'd be right.
Everytime I hit the "should we use GraphQL" question in the last decade we balked because we already had fast REST like APIs and couldn't see a how it would get faster.
To your point it was more of a mish-mash than anything with a central library magically dealing with the requests, so there is more cognitive load, but it also meant we had much more control over the behavior and performance profile.
Not remotely true. There are plenty of web apps that work just fine with a standard fixed set of API endpoints with minimal if any customization of responses. Not to mention the web apps that don't have any client-side logic at all...
GraphQL solves a problem that doesn't exist for most people, and creates a ton of new problems in its place.
The value of GraphQL is also its downfall. The flexibility it offers to the client greatly complicates the backend, and makes it next to impossible to protect against DoS attacks effectively, or even to understand app performanmce. Every major implementation of GraphQL I've seen has pretty serious flaws deriving from this complexity, to the point that GraphQL APIs are more buggy than simpler fixed APIs.
With most web apps having their front-end and back-end developed in concert, there's simply no need for this flexibility. Just have the backend provide the APIs that the front-end actually needs. If those needs change, also change the backend. When that kind of change is too hard or expensive to do, it's an organisational failing, not a technical one.
Sure, some use-cases might warrant the flexibility that GraphQL uses. A book tracking app does not.
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.
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.
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.
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 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.
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.
> 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 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.
I agree! If you're in control of the experience, then I wouldn't choose GraphQL for a limited experience either.
The project started because Goodreads was retiring their API, and I wanted to create something better for the community. I have no idea how people will use it. The more we can provide, and the more flexible it is, the more use cases it'll solve.
So far we have hundreds of people using the GraphQL API for all kinds of things I'd never expect. That's the selling point of GraphQL for me - being able to build and figure out the use case later.
But I would never want to create a GraphQL API from scratch (not again). In this case, Hasura handles that all for us. In our case it was easier than creating a REST API.
You throw away all the debuggability and simplicity of rest for close to zero advantages
Then the security looks also annoying to manage, yeah sure the front-end can do whatever it wants but nobody ever wanted that.
1: one example being tax records with all associated information about tax collecting agencies and taxpayers — it's a lot of data
We've been using it in production for 10 years. Would I change a single thing? No. Every day I come to work thankful that this is the tech stack that I get to work on because it _actually works_ and doesn't break down, regardless of size.
But lots of apps can do with a lightweight pull API that can be tailored, fits the applications' access control model (as points of contrast to GraphQL) and it's less work and less risk than finding, integrating and betting on a GraphQL implementation.