Ask HN: GraphQL or REST?

35 points by throwaway413 ↗ HN
If you were deploying a new API today, however integrated or not with whatever you're currently working on, would you choose to build out a GraphQL or REST API? What stack/tools would you reach for first? Why?

14 comments

[ 2.8 ms ] story [ 40.5 ms ] thread
The whole idea about REST was to get rid of the complexity of SOAP webservices, custom implementations and the like by using the verbs HTTP already has and using "speaking" URLs.

The whole idea of GraphQL was actually to make complex queries easier and more performant (it's a bit like SQL for HTTP).

My personal conclusion (ymmv) is to build REST APIs whenever the API should be exposed to external developers or to be integrated with 3rd party software. On the other side I like GraphQL very much, when the only (main) purpose of the API is to build the backend for a SPA.

> The whole idea of GraphQL was actually to make complex queries easier and more performant (it's a bit like SQL for HTTP).

How about REST's OData?

OData had good ideas in theory but seemed to fail in practice. Most of the biggest OData APIs [1] failed to handle denial of service attacks well. The advice I've heard is never to let OData escape the boundaries of your intranet these days.

GraphQL has better mitigations for sidelining problematic queries (query names, shapes/patterns analysis tools), and doesn't start with the kitchen sink like OData did. Instead, in GraphQL you generally have to opt-in to more complex query operations, at which point you can also lock them down to explicit clients/whitelisted query names/etc while doing so.

[1] NuGet's feeds being the big obvious one to mind where v1 API supported nearly the full OData query set and every version since has dropped increasingly more OData functionality for bespoke REST endpoints.

> Most of the biggest OData APIs [1] failed to handle denial of service attacks well.

Isn't that an implementation issue? Nevertheless IIRC some OData APIs do implement anti-DoS features such as rate limiting.

It can be, but I'd posit its an issue deeper in the heart of the intent and philosophy of OData (versus say GraphQL). OData looked at the basic querying monad and said "wouldn't it be great if I could do that stuff, but just you know remotely" and implemented every operation it could think of on top of that monad. It's like RPC in that way ("wouldn't it be great if function calls 'just worked' over the network?"), in that it started with some okay ideas but then accidentally ran head first into a jungle of XML encodings of security concerns orthogonal to distributed computing but deeply critical if the calling infrastructure doesn't know if the result is coming from the same processor core, the processor core next door, or a machine on a network 5000 miles away in a datacenter run by your competition.

I think some of the "keep it simple stupid" principle of what REST does well that SOAP failed to do, applies between OData and GraphQL. OData did a really good job of very easily connect (via LINQ for many users) "SQL" over the wire, which is great when that's what you need. It's just that "SQL" was never optimized for that and the solutions like rate limiting have to be bolted in on top of the design, and often start to break the original appeal "'SQL' over the wire" as the subset of "SQL" that reliably works shrinks (and therewith shrinks the ability to do some of the ad hoc queries that were the draw in the first place).

GraphQL doesn't entirely escape the orbit of query language as wire protocol issues, of course, but it has the benefit of having seen the issues in OData to learn from, and from what I've seen mitigates a lot of the worst cases in its opt-in approach and the fact that it looks nothing like "SQL" so it immediately doesn't inherit the assumptions of SQL and what sort of queries may or may not be immediately available.

I'd flip that around: depending on which stack/tools I was working in, that would give me a better idea of whether to pick GraphQL or REST.

If I'm building a backend in JS/TS, GraphQL is getting to be just about a no brainer. The tooling for GraphQL, such as Apollo's server products, in JS is fantastic, and can be often highly productive.

On the flipside, if I'm working on .NET (Core) backend, the GraphQL tools are rather lacking still, but a lot of the REST tools are very well refined and capable.

There's a wide spectrum in between of course, too, such as Python which is growing pretty good tools for GraphQL (Graphene I've heard is really good to work with), but also has great REST tools.

Similarly client stack matters too. Again, JS clients for GraphQL are mostly ahead of most other languages. React is great with GraphQL, but some of the other frameworks don't fit the GraphQL model quite as well.

Beyond that, other judgement calls are useful such as development team familiarity and project needs.

the answer at least partly depends upon what your requirements and constraints are.

e.g. if you have particularly demanding performance requirements around latency and speed of decoding messages, then perhaps you cannot use either GraphQL or REST.

I agree with the other answers here: it depends on the use case. But all else being equal, I'd start with a REST API, and build an additional (not replacement) GraphQL API when necessary.

Using GraphQL to create, fetch and write individual objects in a typical CRUD app, without complex object relationships, adds a good bit of unnecessary complexity. Luckily, this is where REST shines.

If/when the domain model evolves, building a parallel GraphQL API for complex (read-only) queries will help solve querying/filtering/complex object fetching better than REST can.

GraphQL for writes/updates doesn't seem worth it for general use cases, but can be appropriate if it matches your domain model.

This depends on the tooling a little.

We are getting a fair amount of cacheing and state management for "free" by using Apollo with GraphQL.

Context and use case are important to help determine this. If you have an existing RESTful backend, think carefully through how complex your front end data may be per page/view. If you’re requiring multiple API calls or creation of custom routes to stitch data together GraphQL can be an ideal technology choice. Definitely would recommend checking out Apollo as well as Airbnb’s Blog Posts on integrating GraphQL/Apollo into their applications.
Rails as the stack and REST as the implementation.

You can then spend most of your time on making sure you have a good understanding of the domain and then design the API to match that understanding.

Rails because you asked what _I_ would reach for :) Once you figure out your domain model you could just generate the REST API.

Rails has GraphQL gems so you could go down that path in the future if desired. Like anything though, GraphQL isn't a silver bullet. If you have a complex data model, that can be exposed and people unfamiliar with the data model will see performance issues.

When I hear API, I usually infer that it means other people will be calling it. The above answers are in context of that. If you really mean a back-end to your web app that nobody external will be calling, ever, then it really doesn't matter what tech stack or methodology you use. In that case, there are other factors like time to deliver and if there is a team building it, then it helps to use a common methodology (e.g. REST).

Isn't rails an overkill compared to something like sinatra or the other 500 ruby based opinionated frameworks in between?
It might seem like overkill at first, but if you start a project from Sinatra, you’ll end up implementing a lot of rails features that won’t be as well thought out or integrated. If “weight” is a concern, it’s pretty easy to turn off rails features that you don’t need.
RESTful microservices deployed to AppEngine + Cloud PubSub. With MongoDB for static json assets. And either Firebase or Cloud DataStore for all metadata, config, and application state. Strong isolation between different modules. Set things up right and it will run forever with fixed (or rather, predictable) costs and zero maintenance.

I do appreciate how productive GraphQL and frontend frameworks like Gatsby can make developers. Having seen it first hand in hackathons ;)