Hacker News new | ask | show | jobs
by eddd-ddde 924 days ago
If you need to request multiple REST resources for a single "operation", then you don't have enough REST resources defined. [1]

Just make another endpoint for getting the whole thing in one go and call it a day, don't try to overly generalise your API.

Going even further, your server requests to the database could be similar as well, one query to get everything needed, then you don't even need to worry about server to database distance!

[1] https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert...

4 comments

My practical experience with that idea is pretty negative, at least with any degree of scale (either in how widely used the resource in question is or in number of people working on the system). I saw a multi-year mess made at a company when the widely used `ResourceA` got endpoints for `ResourceAandB` and C, and D, and E... for the reasons you mention. Then somebody added some fields to make a `ResourceA'` with a specific additional feature. Then somebody removed unused fields from `ResourceA'` for better performance, creating different subsets. We ended up with some `ResourceAandC` things moving to the new `A'`, some features did a frontend join with multiple queries, some things moved to a new superset resource named `ResourceA''`. It was a Cambrian explosion of variants of types. Like violence, it ended up being "if one doesn't work, just add more."

It's easy to say "don't do that" but shit happens: large legacy codebases, social factors, and individual incentives of backend and frontend teams with deadlines. GraphQL makes the outcomes of these situations a lot more manageable. In that way I think of it as a social and organizational technology as much as a query technology.

> It's easy to say "don't do that" but shit happens: large legacy codebases, social factors, and individual incentives of backend and frontend teams with deadlines.

I don't buy this argument. Imagine if an airplane manufacturer had the same philosophy. "We can't just substitute that component because it wouldn't fit the existing frame... Oh but wait, we can't just change the frame or the new component to make it fit because of social factors within the engineering team. Let's just tack it on as originally planned and then work around the issue by implementing a complex solution in the software to make up for the structural design flaw.."

That's basically the Boeing 737 MAX story. We know the result of that philosophy.

Software isn’t nearly as expensive as building airplanes, and the cost of being wrong is infinitely lower. That’s why we build it fast, and iterate quick. It’s not a good comparison.
This is 100% my experience, and this is a very astute observation :

> It's easy to say "don't do that" but shit happens: large legacy codebases, social factors, and individual incentives of backend and frontend teams with deadlines. GraphQL makes the outcomes of these situations a lot more manageable. In that way I think of it as a social and organizational technology as much as a query technology.

I think people miss the point a lot when ranting about graphql. It’s not particularly their fault, I didn’t get it either until I experienced multiple massive rest messes like you describe.

Also, as social/org tech you don’t really see the benefits in small teams / simple products / small apis. It just feels like extra complexity at that size.

> Just make another endpoint for getting the whole thing in one go and call it a day.

That's pretty much the point (well, one of the main points) of GraphQL... precisely so you don't have to do that. Want to request a new object or list of objects? Request a new field on an existing object? You don't have to go "make another endpoint", you just change your GraphQL query.

This is really nice for iterating, though it does have some downsides (eg it's easy for the person iterating away on the FE to not have to think about the cost of querying that data on the BE).

GraphQL does have a few other advantages though, like being able to build your typing around it (again, doable with REST but with more work).

I also agree with that!

I'm not actually opposed to Graphql as a technology, One of my favourite pieces of technology is actually PostGraphile.

I just believe it's easy to misuse it (in similar ways to an ORM) that result in not utilising server capabilities to their fullest.

The problem with REST (or really, any current non GraphQL solution) is there is only an implicit link between the consumer of a field and the query declaration. So, REST queries are append only, especially at large organizations where incremental perf improvements are less good than accidentally bringing down the site is bad. That’s the failure mode of specialized REST endpoints that deliver exactly what a given view needs.
If you require something more explicit, you can totally define strict schemas that your API adheres to.

Would you elaborate on "queries are append only"? I fail to understand the downside you mention.

If you mean that you can only append to the data you return from a resource, you can use versioning to deprecate properties on a resource.

"Make another endpoint for getting the whole thing in one go" is a pretty good description of what GraphQL does. Except instead of writing an endpoint in some general purpose language you define it declaratively.
> is a pretty good description of what GraphQL does

Maybe but the implementation is orders of magnitude more complex compared to simply making a couple of DB queries and then sending a JSON.

Sure. The implementation of React is orders of magnitude more complex than simply making a couple of HTML templates and sprinkling in vanilla js inside script tags, the implementation of sqlite is orders of magnitude more complex than simply de/serialising your data to a json file, and the implementation of nginx is vastly more complicated than simply exposing a web service directly to the internet.

Don't use tools unless you benefit from them. Some people benefit from being able to define JSON responses in a graph query language.