Live data from Hacker News

GraphQL vs. REST APIs: a complete guide

airplane.dev

41–50 of 103 posts

Re: GraphQL vs. REST APIs: a complete guide

#41

Earlier quoted context omitted.

One thing Id suggest - "gRPC might be an option but most teams dont need it" - needs a revisit. As a backend-dev (who does front end when needed - and that too by slapping NextJS on an API) I have found starting from a grpc set of services and generating http/openapi specs from it to be much for maintainable and understandable than starting with the OpenAPI spec and working "inwards". Apart from a (mostly) single sou…

If we compare gRPC to OpenAPI, we get the following. gRPC will be faster at the tradeoff of complexity. You need more tooling, you cannot easily inspect binary traffic, you cannot simply call gRPC from the web, you need a grpc web proxy, proxies and API gateways are more complex for gRPC than for an OpenAPI/REST-ish API, and the list goes on. I can put my protobuf in a registry, but the same applies to OpenAPI. So wh…

Here's a bunch of random points (this deserves a full blog post)

- it's not about performance

- OpenAPI needs and has tooling (it just doesn't work) - think about documentation, client/server code and evolution support for forward/backward compatibility, type safety, etc.

- you can build monoliths and microservices with both

- gRPC / protobuf gives you a pragmatic separation of concerns (and typing among other things)

- gRPC allows exposing REST/OpenAPI with defualt tooling and it works

- there's an extensive set of best practices that combine the best of both worlds - just read https://google.aip.dev/

- if the workd prefers GraphQL, you're out of luck

- gRPC / protobuf help you focus on the actual contract and make everything else (that's 90% of time) a non-problem.

---

Disclaimer: I'm in the grpc (and protobuf) camp and have built APIs with REST, Thrift and gRPC/Protobuf for more than 15 years (gRPC mostly last 5 years) As an infrastructure startup we have to both expose and consume both REST and gRPC.

If you build APIs and decide to handle the above manually - you must feel productive doing work that compilers and code automation tools have been invented for. However tooling should automate it for you.

Re: GraphQL vs. REST APIs: a complete guide

#42
I take not mentioning hypermedia in a post discussing REST as a huge red flag. The author mentions Roy Fielding's dissertation, but apparenly they didn't read it thoroughly.

Furthermore, I believe that a huge confusion comes from not understanding what a "resource" is: it is not a database table*; it is not your domain model*; it is a _representation of state_. Like this very orange page you're looking at. This whole page is the resource identified by https://news.ycombinator.com/item?id=35014395. Just like the stylesheet for this website is a resource identified by https://news.ycombinator.com/news.css.

* It may be, if that's the _representation_ you want.

Re: GraphQL vs. REST APIs: a complete guide

#43
There seem to be a lot of people pushing back on GraphQL who often don't seem to understand what it really is, or what it can do. They often seem to think that it's super complicated to build and use, and that REST(-ish) APIs are somehow magically simpler and easier.

Are RESTish APIs simple to build? I mean, yeah. You can have a server running serving an endpoint in like a minute in most programming languages. But FWIW, this also applies to GQL. Take a gander at any GQL resolver tutorial. But is that really what makes it simple?

When you build APIs, they aren't made to exist in isolation. They're made to be consumed. Ideally, they should be easy to consume, which can mean a lot of things.. but "it's easy to send an HTTP request" is not one of those things.

They're easy to consume if they are documented and come with schemas. They are easy to consume if there is tooling to generate fully typed clients for them. Arguably, OpenAPI schemas could fit this description, but in my experience, OAPI support is really varied, both on the server and for clients. Generated clients tend to be lots of code and incredibly clunky. Support server-side is heavily reliant on the server libraries being capable of exposing schemas in some way. In some languages this is trivial, but in e.g. javascript or typescript, you will need some way to expose your types. Just having typescript interfaces isn't enough(without extra tooling or reflection).

GraphQL is typed by definition. The schema is the API, and the types, and the documentation. We have great tooling to generate code in any language, and code-first resolver libraries(like the excellent pothos-graphql.dev) make building your schema along with your resolvers an absolute joy.

Then there's things like the N+1 problem. RESTish APIs are sort of "procedural". Each endpoint is usually a resource, and if you want to fetch a resource and its related resources, you will often have to fetch it and them separately. You can also embed them in the resource, or you can resort to all sorts of not-very-standardized methods of conditionally expanding relationships to do it, which is already just sort of doing what GQL does, except much worse(and is I think not supported in OpenAPI at all?). In GQL, you can also run into N+1, but modern libraries make this super easy to solve. Either they can tightly integrate with something like the underlying ORM, or you can write dataloaders for your types, so that every time a specific resource is requested en-masse, it is always loaded efficiently. Not so much for REST, unless you apply very careful engineering and design.

GraphQL just makes all these things such a breeze. There are some things you need to think about, of course. Query complexity is one thing; you don't want someone to bring down your server using 30-level nested query. Thankfully, people have been using GQL for years at this point and most of these problems are solved, and many of them incredibly neatly.

Re: GraphQL vs. REST APIs: a complete guide

#44

I take not mentioning hypermedia in a post discussing REST as a huge red flag. The author mentions Roy Fielding's dissertation, but apparenly they didn't read it thoroughly. Furthermore, I believe that a huge confusion comes from not understanding what a "resource" is: it is not a database table*; it is not your domain model*; it is a _representation of state_. Like this very orange page you're looking at. This whole…

[dead]

Re: GraphQL vs. REST APIs: a complete guide

#45
post #33
post #26

Earlier quoted context omitted.

Simplify that to: - REST by default - everything else might be an option, but you need to justify it with specific reasons. Also, having a JS-driven front end or multiple teams is not an automatic justification for the complexity of GraphQL. GraphQL is a huge burden, for very little practical gain. Most companies have very small number of examples of conflict areas where queries need to be optimized, and for the most…

How is GQL a "huge burden"? Would you care to elaborate?

GQL, in no particular order:

- GQL allows unbounded arbitrary queries. The awkward workarounds turn it into REST with none of REST semantics

- default query method (POST) cannot be cached by literally anything in the infrastructure because POST is not cacheable by definition. The awkward workarounds require you to parse and look up fields in both request and response. Both of them arbitrarily large.

- instead of delegating requests to optimized queries (db or services) you now collect all that data manually, in-memory, on the server with little to no insight into what the data is, and how to optimize its retrieval

- default types doesn't provide useful primitives like dates

- you now have to keep up with evolution of every single microservices you depend on

There's more that I've forgotten.

It's really good for building internal tools that usually have different requirements than what existing APIs provide you

Re: GraphQL vs. REST APIs: a complete guide

#46
I've been writing flask apps for a while (using sqlalchemy as my ORM) and find myself repeating code all the time when I create GET and POST end points for all my models.

Is there a better, more automatic way to generate GET and POST endpoints automatically when I create a new model?

Re: GraphQL vs. REST APIs: a complete guide

#47
post #38
post #33

Earlier quoted context omitted.

How is GQL a "huge burden"? Would you care to elaborate?

I could write a book on this, but just a few: * your teams will now spend a big portion of their time thinking about GQL primitives and mapping and syntax (oh my) and otherwise caring for and feeding this beast. * you still haven't solved the underlying problem -- you still have to figure out why your GQL requests are hammering the back-end(s...let's not forget that a lot of this stuff came from poor decision-making…

> * your teams will now spend a big portion of their time thinking about GQL primitives and mapping and syntax (oh my) and otherwise caring for and feeding this beast.

What exactly do you mean by this? My team spends exactly zero time "thinking about GQL primitives and mapping and syntax"? What programmers have a problem understanding GQL syntax? I have explained GQL and set people to work in a 30 minute session. I've even had non-technical people write automated tests for APIs. If they can't write the queries themselves, they can simply use any of the great query builders(like apollo studio or what have you), where they can quite literally explore the entire schema, with documentation, and point-and-click their way through building any query.

> * you still haven't solved the underlying problem -- you still have to figure out why your GQL requests are hammering the back-end(s...let's not forget that a lot of this stuff came from poor decision-making re: microservices!), only now it's indirected and harder to optimize.

How is this really any easier with RESTish APIs? In the end, this boils down to how you are doing observability. If you don't do any observability, you are shit out of luck whether you use GQL or REST. With GQL, you can quite literally automatically instrument your entire schema and get detailed tracing information for your entire graph. I have sentry set up to trace all our requests from our frontend, to our GQL gateway, to the subgraphs, to other services they call out to and even time taken doing database queries. It was a few lines of code.

> * ...oops, you forgot to implement all the corner cases of your GQL schema! Go back to 1 and start over.

Corner cases? If you have some underlying data you need to expose, the difficulty of exposing this data in the most appropriate manner comes down to the complexity of your data, and whether you use GQL or REST to expose it doesn't really change it. With GQL, types and relations are at least "native" - they are the source of truth. With REST and something like OpenAPI, you'll constantly be fighting limitations and have to trawl through hundreds of endpoints, some of which might be doing extra stuff for the sake of ease of consumers, etc. Feel free to elaborate on what sort of corner cases you have in mind. This sort of vague hand-waving isn't really useful.

Re: GraphQL vs. REST APIs: a complete guide

#48
post #26

Earlier quoted context omitted.

Simplify that to: - REST by default - everything else might be an option, but you need to justify it with specific reasons. Also, having a JS-driven front end or multiple teams is not an automatic justification for the complexity of GraphQL. GraphQL is a huge burden, for very little practical gain. Most companies have very small number of examples of conflict areas where queries need to be optimized, and for the most…

I haven't used it a lot but one of the benefits of GraphQL that caught my eye is you get to specify what you want returned. So, for example, instead of 20 product objects (all available properties) you can get 20 products with name and price. Also, as I understand it, when implemented properly, you can get more complex (?) data back. For example, instead of getting 10 orders, and then 10 more requests for the items f…

That's not an advantage, from the DB side the two queries are indistinguishable because they use the same indexes. They will take virtually the same CPU to complete.

If your user has authorization to access this extra data, the actual cost of sending those extra fields properties over the wire is ridiculously trivial.

Think a kilobyte or two, if not a few bytes.

Any justification you think you have for just sending the name + price is utter bullshit. You would save vastly more in bandwidth by not sending whatever dumb graphql code you wrote as part of your front-end build.

That is, unless you are Facebook or Google and have already optimized the hell out of your front-end libraries.

Which I guarantee you aren't and haven't done.

Re: GraphQL vs. REST APIs: a complete guide

#49
post #16

REST is basically a subset of GraphQL.

From a caching perspective REST is a superset IMHO.

There's a lot to caching that REST gets wrong. It thinks in terms of URLs being cacheable, but that's very limiting. GraphQL caches at the level of the objects in the response. Almost every REST API will return multiple objects from one URL. With GraphQL, newer data coming in from query2 can update components showing data from query1 if they both reference the same object even if query2 is a different URL. REST just doesn't have those smarts. Yes, a HTTP DELETE request will clear the cache for a particular URL, and there's no equivalent in GraphQL, (that I know of) but I don't think I've ever been able to take advantage of that in real life.

At the network level, GraphQL can automatically set cache headers depending on the content. REST doesn't know what you're sending, so it's up to you to know that when you start sending mixed data (to save clients a roundtrip), the cache header may be impacted. https://www.apollographql.com/docs/apollo-server/performance...

On the client-side, caching with GraphQL is far ahead of dealing with a REST API. It knows more about what data it has in cache so it's better able to automatically avoid network requests. Further, a cache-and-network fetch policy is just another parameter for your query and the plumbing for that is handled transparently.

Re: GraphQL vs. REST APIs: a complete guide

#50
post #47
post #38

Earlier quoted context omitted.

I could write a book on this, but just a few: * your teams will now spend a big portion of their time thinking about GQL primitives and mapping and syntax (oh my) and otherwise caring for and feeding this beast. * you still haven't solved the underlying problem -- you still have to figure out why your GQL requests are hammering the back-end(s...let's not forget that a lot of this stuff came from poor decision-making…

> * your teams will now spend a big portion of their time thinking about GQL primitives and mapping and syntax (oh my) and otherwise caring for and feeding this beast. What exactly do you mean by this? My team spends exactly zero time "thinking about GQL primitives and mapping and syntax"? What programmers have a problem understanding GQL syntax? I have explained GQL and set people to work in a 30 minute session. I'v…

I don't want to get into a debate about this. I've told you what I believe and why I believe it.

I will add this: if you are truly at a company that has adopted GQL and you are not spending significant eng time on it, you're either not measuring it (ding ding ding!), or you're in the vast minority. Or maybe you're just too early, I suppose. Perhaps relevant to that point: the complexity of explaining GQL to an unfamiliar developer is not what I'm talking about. Most people can learn enough GQL to make really awesome footguns in a single 30 minute session!

REST is easier because, instead of having to do all of that instrumentation you're talking about across an entire query graph (you've described quite a lot of infrastructure there, btw...), you have endpoints, which correspond to specific needs, which you can then optimize appropriately on a case-by-case basis.

When all you expose is a structured query language that anyone can use, you have made things (perhaps) easier on a single dimension (consistent interface), but you have abstracted all of the other problems and made them harder. And you have all of this other infrastructure to look after now, too.

Post reply on HN