Hacker News new | past | comments | ask | show | jobs | submit login
REST in Peace. Long Live GraphQL (freecodecamp.org)
94 points by quincyla on July 24, 2017 | hide | past | web | favorite | 88 comments



I'm pretty disappointed by this title.

I know that it might be said in fun - and is an easy way to get clicks, but it feeds into the narrative of new, shiny tech. As the article points out at the end, there are very real engineering tradeoffs with GraphQL - and the answer isn't as easy as REST is dead, anachronistic technology that no engineer should consider (the XML analogy felt particularly inflammatory).

Kelly and I were chatting about GraphQL, and his post might be a more thoughtful engineering post: http://kellysutton.com/2017/01/02/do-we-need-graphql.html (the title - Do we need GraphQL? - is at least the way I'd expect engineers to approach the problem, where he discusses the tradeoffs)

In my MongoDB series, I point out a past case where Free Code Camp fed the hype, by telling engineers that the reason everyone had to learn the MEAN stack was due to employability in the software industry: https://medium.freecodecamp.org/the-real-reason-to-learn-the...

(you had to dig into the article to realize that their argument was more nuanced, and that they taught SQL first before MongoDB)

A number of "engineering" posts are not written as a thoughtful engineer might, and are in many ways marketing for the products sold (like a training program or code camp).


>A number of "engineering" posts are not written as a thoughtful engineer might, and are in many ways marketing for the products sold (like a training program).

I think this is a great insight that is often overlooked in tech marketing. When any vendor comes up with a product that claims "[industry standard] is dead, use [our product]", there should be alarm bells ringing already.


>When any vendor comes up with a product that claims "[industry standard] is dead, use [our product]", there should be alarm bells ringing already.

Seen this from quite a ways back. When .NET came out, I remember college students in my neighborhood (e.g. when hanging out at some tea shop or restaurant), asking me (they knew me, and that I was in software), in a concerned tone, stuff like:

"We hear that now that .NET has come, Java will be dead. Is that right?"

I used to have to disabuse them of such nonsensical notions. Not that Java will live forever, but obviously a mature and widely adopted technology is not going to die off overnight. Such is the hype, though, for the new and shiny.


The author of this piece is selling a Pluralsight course on building GraphQL applications, so qui bono certainly applies.


Yeah, it's really unfortunate that people feel the need to trash other technologies when promoting something.

I'm a big fan of GraphQL and tried to write up a more low-level comparison here: https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b


  What is GraphQL?
  GraphQL is all about data communication
Somehow it reminds me of good old "The S stands for Simple": http://harmful.cat-v.org/software/xml/soap/simple


Thank you for reminding me harmful.cat-v exists, this stuff is hilarious.


That place makes me feel like there's some hope in this industry.


The reference implementation of GraphQL has a patent grant identical to React [1].

It does not seem wise to use anything with that rider if you have or would like to leave open the possibility of having patents which you license to / enforce against Facebook.

The argument for patent disarmament strikes me as reasonable, but some companies have novel tech they would like to license to Facebook, and restricting the use of software like this seems a pretty severe violation of the notion of Free Software.

1. https://raw.githubusercontent.com/graphql/graphql-js/master/...


Check this out https://medium.com/@dwalsh.sdlr/react-facebook-and-the-revok...

might not be as bad as you think


Anyone got experience transitioning a large production site from REST to GraphQL? I'm aware Yelp did this recently, wondering about any pain points.

In particular, I have some FUD about how to go about rate limiting, when in theory a single request could grab every resource that the client is authorized to retrieve, and thrash the database.

Looks like Github counts/restricts the number of total nodes returned: https://developer.github.com/v4/guides/resource-limitations/

Also is there any protection against pathological requests? (e.g. if there are loops in the object graph, can I build an arbitrarily deep GraphQL query that will take an arbitrarily long time to complete?)


There is a video on the Apollo GraphQL Youtube channel where an engineer from Yelp talks about the process of switching from REST to GraphQL. (Along with a talk from Airbnb, who are currently in the process of the switch.)

https://youtu.be/rapO30fpREg?t=1582


>Also is there any protection against pathological requests? (e.g. if there are loops in the object graph, can I build an arbitrarily deep GraphQL query that will take an arbitrarily long time to complete?)

I've seen some GraphQL servers in the wild that will respond to any query, so it's entirely possible to make abusive queries to bring a server down.

Some attempt to estimate the query complexity, and deny requests based on how long the server thinks it might take. Others, such as Facebook themselves, whitelist which queries are allowed (I have no affiliation with Facebook, this is just what I've heard).


Also in response to protection against malicious requests, you may find the following link helpful.

It goes over several ways to secure your endpoints, along with pros and cons for each.

https://www.howtographql.com/advanced/4-security/


Some random points:

* The caching clients (Relay, Apollo) out there are dog slow for medium to large response payloads. (they're working on it)

* It can add more complexity than you need if used for service<->service chatter (pure RPC may be preferable)

* It's still pretty damn awesome as a data layer, especially to public clients


Thanks to some help from nevir, we are working on a new Store API design that will allow for pluggable stores. Theses stores can be tuned as needed for different performance models.

We are also working on speeding up how the default store handles large response data


> The need to do multiple round trips to fetch data required by a view: With GraphQL, you can always fetch all the initial data required by a view with a single round-trip to the server.

I'm not sure what's different. You can actually implement the same with plain old http api's, also.


Especially since avoiding n+1 query situations involves hand optimizing a lot of stuff anyways. In my experience it's not really any less work than just aggregating stuff in a regular HTTP API, but it does seem to give a better developer experience on the frontend. At a certain scale, I think it could be worth the investment, but I don't think it really lives up to the hype.


> Especially since avoiding n+1 query situations involves hand optimizing a lot of stuff anyways.

Rarely. Assuming the GraphQL server is using REST endpoints behind the scenes, i'm yet to find a request waterfall that required manual rather than automatic optimizations. I'm assuming there are cases where a manual path is faster, but they're less common that you'd think.


Not sure how magical your automatic optimizations are - but my experience does not at all mirror yours. i've certainly had to hand-optimize queries to improve performance, on top of the query already being automatically optimized. Removing unused data, tying across custom relations and moving things into different forms of caching are all quite manual efforts I've done plenty of. So, not sure how "less common than you'd think" holds up to scrutinization. I'm just one counterpoint.


Mostly i'm referring to the methodology I followed here: https://dev-blog.apollodata.com/optimizing-your-graphql-requ...

I haven't looked into optimising other types of architecture (eg GraphQL server talking directly to the database), but there seem to be plenty of solutions that people are happy with.


That doesn't touch upon the N + 1 query problem at all.


Can you tell me which particular problem you're talking about? When people talk about GraphQL and the n+1 problem, they're typically talking about the problem which Dataloader solves, and this is the problem this article builds upon.


The N + 1 at the database level implies that for every object's remote relations you have to do another query instead of subsuming the object in a large invididual SQL query.


well maybe on the frontend it looks good, but on the backend? meh parsing such a query is not painless. and maybe "simple" queries are looking good and simple, complex and bigger queries and big schema's are really really akward to implement.


Readily available packages in most languages can parse graphql queries for you.


Right but then you have to build a custom http api for each and every new view. Oh, and now you altered the view a tiny bit and need some more fields? Add yet another api. Oh, you did a redesign and you only need a tiny bit of data now? Either add another api again, or deal with the fact that you're wasting bandwidth by sending a bunch of unnecessary data.


or you can pass the fields you want in your request, and then realizing it would be simplier to fetch all your data in only one endpoint to avoid multiple roundtrips, create a giant request-parsing-data-fetching logic to respond with some kind of nested data, yeah GraphQL is useless because we can build a new one from scratch for each of our projects ;)


...at which point you reinvented the wheel and it's very likely that the GraphQL library for your language works better and maybe faster.

<winks>


You can but you have to write all the allowed query combinations. Graphql is more flexible. It's also declarative, so you can provide a widget with the schema it needs.

Another benefit of graphql is that is a "lingua franka", you can use it internally, between microservices, etc.


Indeed, some of the points which I loved the most when I started using it was how it allows to avoid writing any serialization method, how it helps centralize permissions, and, as said in the article, the simplicity it adds if you want to add fields in your queries.


The difference is that in pure RESTful APIs you don't have that ability anymore. So, when all you know is RESTful design, GraphQL is solving a problem. But in the end you'll still implement a "plain old http" API when interfaces have stabilized and performance matters.

Until then, what you gain is "only" a completely decoupled backend that will accommodate frontend developers work in exchange for more generic logic in the backend. Not necessarily a bad thing, if this is how your shop works.


But you have to do it manually. GraphQL removes that pain (or at least that's my understanding:.


It removes the API design, versioning, etc. pain which is probably huge in an organization as large as facebook.

But there's still going to be a decent bit of backend tuning which in my experience is the hard part (unless the organization is so dysfunctional new API version design meetings descend into a hostage exchange).


Yes, that's true. But I don't think that's legit within the technical and absolute definition of REST. Perhaps they used that strict definition in order to differentiate the product?


Like PostgREST does :)


I love me some complex async/await chains!


> When it comes to versioning, GraphQL has an interesting take on that. Versioning can be avoided all together. Basically, we can just add new fields without removing the old ones, because we have a graph and we can flexibly grow the graph by adding more nodes.

In my experience, versioning a RESTful API is not hard (much has been written about the various approaches). The cases when versioning does get hard usually correspond to major system architecture changes (e.g., restructuring fundamental relationships between data models), and in those cases, I suspect GraphQL wouldn't help a whole lot. You may still need to build some kind of compatibility layer to support older versions.

Other than that, adding new fields (which account for 90%+ of the changes to APIs I work on) are just as easy to add to RESTful endpoints. If payload size really does become an issue (it's usually negligible), it's easy enough to add a parameter or two to control the extent of the response data.

As for reducing round trips, I do see the advantage of using GraphQL, though to be fair, well-designed RESTful APIs can avoid excessive round trips as well - they just require a bit more coordination between client and server development (which is a good thing!). RESTful APIs also have the advantage of mutation payloads that look like their corresponding response representations.

To address some of the potential concerns with GraphQL (such as resource exhaustion), I believe it would require more development time/resources for most of the projects I've worked on - even after factoring in any technical debt brought on by RESTful API limitations.


The JSON API specification resolves the 2 major problems people have with REST:

The need for multiple round-trips to the server and sparse field-sets (returning only the fields needed):

http://jsonapi.org/format/#fetching-includes http://jsonapi.org/format/#fetching-sparse-fieldsets


I always enjoy these absolute "X tech is dead long live tech Y".

Note that earlier the top story on HN was about MSPaint and the top comment said:

> "All the comments that "you can just use X to do Y" is missing the point that Paint just works"

REST still (and will continue to) just work for most people, I'm sure some will switch or some will go straight to GraphQL, but lets not just go ahead and declare the whole thing dead. Haha.


I tried to build a GraphQL server, but found it impractical since I didn't want to use Relay or Apollo on the front end. Formatting the query strings just made a mess and was a lot of trouble considering the simple resources I needed. Dealing with authentication and authorization looked like it was going to be a headache as well. I ended up going back to REST.

Should I give it another look? Was I too quick to dismiss it?


I've just started building a server/client seed that I can use in the future for my personal projects.

The concerns you have with the front-end are founded. However, you can send a request to a GraphQL endpoint in a very REST-like manner. If you can build a wrapper to create the query as explained in the Stack Overflow post, you can essentially negate the need for Relay/Apollo. (At least until you need any of the helpful tools they provide.)

https://stackoverflow.com/questions/42520663/how-send-graphq...


One thing that may be helpful is a smaller client like Apollo-link (https://github.com/apollographql/apollo-link) that can grow to fit your client needs.

The basic http link includes middleware for passing auth to the server.

I hope that helps!


Not sure if you're not going to use it with Apollo/Relay. These clients help you format queries in JS with Babel transforms. These transforms also are what help couple your front end to your back end by validating queries at front end compile time webpack bundling), which is a huge element of the charm imo.


+ they can help you implement caching strategies / offline modes


Try PostgREST


I guess this makes me sad. Apparently REST has come to mean such a small and specific thing that a REST vs. GraphQL comparison makes sense.

There actually shouldn't be anything contradictory about choosing the GraphQL interface for a REST API.

Also, before anyone jumps in head first on this, keep in mind the downside to things like GraphQL. Your data API is a promise to your clients and GraphQL presents a flexible, unbounded API. This puts a heavy burden on the data service: it's going to have to handle all the valid queries and perform well doing it.

Further, there are a lot of things that will have an impact on this, such as how/where the data is persisted and what the data model is, how the service needs to scale, etc. These will all be impacted by using GraphQL as your data interface. It's a lot to commit to, especially if you aren't sure how these things will change over time.


> Apparently REST has come to mean such a small and specific thing

It's called an argumentative straw man. The article attacks… something, but that thing ain't Rest, clearly. But ooooh boy, must it feel satisfying for Samer Buna to topple it over!

HN readers should not fall for the oldest trick in the book.


Reading all the skeptical comments make me really happy. Maybe it's just HN but I've got the feeling the community is starting to be much more "professional" in the sense that it looks for some real benefits before jumping to the brand new shiny tech.

Maybe the recent wave of JS framework had at least this beneficial side effect.


Typical "RIP older tech, long live new trendy tech" blog posts designed to get beginner experts hyped about something they'll probably never use.


  "who in their right mind would use XML over JSON today?"
Lost me already... there are lots of reasons to still use XML today. And since someone is going to ask, here are some:

* you want to use xpath

* you want to communicate with an enterprise app (salesforce, magento, etc)

* you need strongly-typed message-passing in a human-readable well-understood format (rules out messagepack, etc)

* nobody actually documented the API, but they might have a WSDL


Or your data is…you know…mark-up. Imagine a biology textbook, or legal contract, with inline citations and entities. There’s lots of marked-up human text around, even if that’s not what you’re sending to a JavaScript front-end. (Ironically, all of our JavaScript front-end frameworks are ultimately building mark-up as documents for human consumption.)


I read that too and assumed the author was confining that to the type of development they do. Either way it comes off a ignorant and even a little rude.


Then to read the planet’s name, we ask: GET - /planets/1 And to read the films titles, we ask: GET - /films/1 GET - /films/2 GET - /films/3 GET - /films/6 Once we have all 6 responses from the server, we can combine them to satisfy the data needed by our view.

this is stupid there is no need to go multiple rounds?


Yeah, this seems like terrible API design that, while it may be constructed to make a point, sort of obscures whether I should actually care.

GraphQL seems a lot more complicated to consume/explore than REST, and it looks like I need to know a good bit about how the data is shaped before I write a line of code - something that can change, and something that the current REST endpoint system (happily) doesn't need.


I've often wondered about this example: 1) Relational databases already had network interfaces 2) SQL isn't perfect, but it has been reliable for a long time 3) Why we didn't increase the performance and security of SQL interfaces, relational databases and just expose those to client applications, including in the browser, directly?

Ok, there are a lot of reasons.

I worked on a project once that was essentially a "data platform", kind of a SQL firewall to "any data" (a bit of a stretch, but that was the concept). You could put any data system (relational, non-relational, web services, etc.) behind it, but then join across heterogeneous systems using plain old SQL. You had a query language and a network interface, and since it was separate from the actual databases themselves, you could do some interesting things with security, caching and scalability in a different layer.

GraphQL has always seemed like the same kind of query abstraction over data, with a network interface. Props to Facebook for making the tech and releasing it open source.

This also makes me think about the command query responsibility separation (CQRS) pattern, a similar discussion.

EDIT: Also, lest we forget OData... which never really took off, but offers similar functionality.


Why "never really took off"? It's quite widespread in MS-related enterprise world. And it provides a lot of value there. It's just it wasn't adopted widely by the others because of different reasons


Well, I suppose that's a relative judgement. I agree it is more widely used in the MS-related world.

In my thinking, "taking off" would have been if the rest of the ecosystem had embraced it. OData is shared as an open standard (http://www.odata.org), but there is something about it where I still haven't seen the broader ecosystem embrace it (although certainly many have adopted some of the style of OData REST endpoints). That said, compared to where it was when it first came out, OData is still getting a lot of attention. I think opening up the tech is what kept it alive, to be honest.

Just for kicks, I did a Google trends comparing OData nd GraphQL, kind of interesting: https://trends.google.com/trends/explore?q=odata,graphql


about exposing databases directly, https://postgrest.com comes quite close to what you are describing


Sure does, and that is one project I have been watching for a while :) Thanks for sharing it!


Basically, GraphQL is a revamping of SPARQL (you know, the W3C language to query RDF databases). FYI, DBPedia is a big big endpoint for these old-school technologies.

My question is then: - will there be a "standard" way to describe the data model (aka vocabulary) of your GraphQL endpoint? Something like RDFS or OWL.


This is entirely incorrect.

GraphQL is a wrapper around your service layer, or worse, around a number of ad hoc data sources. That service layer or those data sources may query SPARQL services.


So GraphQL is a graph abstraction over REST APIs, at the cost of massive REST calls to rebuild a graph. True?



You can wrap REST APIs with GraphQL. And yeah, as you you mention, caching is usually important in such scenarios. In JS there's https://github.com/facebook/dataloader which help with the caching. I am using a Java implementation with Google's LoadingCache.


There is a lot of FUD from the GraphQL side of this debate, and even overlapping goals with REST. From the article:

>With GraphQL, the client speaks a request language which decouples clients from servers. This means we can maintain and improve clients separately from servers.

This is actually how the web works right now. Browsers (clients) evolve independently from web pages (servers). Even the author of REST said it is "intended to promote software longevity and independent evolution". Standards are governed by standards bodies such as IETF, IANA, W3C, WHATWG, etc., not a single corporation like Facebook.

I think only time will tell if this is just another fad that took off but didn't age well, like SOAP.


If you control both the client and the server, there are lots of shortcuts you can take. As you say, that’s not the problem that REST was trying to solve, though.


Compared to a by-the-book REST-api, GraphQL is more powerful. But we always end up making specialized endpoints anyway.


The article starts with: > With GraphQL, the client speaks a request language which: 1) eliminates the need for the server to hardcode the shape or size of the data

And then ends with: > There are some mitigations we can do here. We can do cost analysis on the query in advance and enforce some kind of limits on the amount of data one can consume.

... so basically you did nothing in the way of perf but add complexity.


How do people solve performance problems with GraphQL?

I can imagine that it can be quite slow internally with multiple joins/subqueries in the datastore.


It depends on how you write your joins, PostgreSQL does a great job as long as you have the right indexes in place, certainly much faster than doing sequential queries.

My take on it https://subzero.cloud (GraphQL and REST api for your database), built on top of https://postgrest.com


As your REST API grows, you will often want to implement search endpoints, and allow queries using fields you've defined. GraphQL is just the search endpoint for your REST API, if you need to allow so much flexibility that implementing it all would be troublesome.


Not sure what you're using for your api framework, but you can definitely fetch only particular fields on your get requests with Django Rest Framework.

Also, you can definitely version nicely. You just have to document it well. If you're supporting different api version in you're bound to add more code, not sure what that argument is about, since I assume (could be wrong) you'd have to define a new schema and add new logic to handle the queries in the translating layer, correct?

Also, the author makes a bold title and then goes ahead and mellows it in the first few paragraphs. Stick to it or don't do it at all.


REST is certainly not dying anytime soon, GraphQL is just solving the data fetching problem in a different way. My intro to GraphQL came from researching GitHub's move towards it. For those interested, I chatted in detail with API manager there on my podcast. Transcription is also available for those who want to skim. https://www.heavybit.com/library/podcasts/jamstack-radio/ep-...


GraphQL needs a good server side library. But for e.g. C# I've found only libraries that can't be called stable. With stability I also mean who is developing and maintaining the code? If it's just one person effort it can't be called stable. I have understood it's much better in Java side, so perhaps if you can start your backend with Java/kotlin/Scala you are good to go.


If I understand GraphQL correctly, it sounds like I will be re-writing queries multiple times across different clients (android/ios/web). For the majority of (simple) read operations this doesn't seem like such a big deal. But for write operations, wouldn't this mean having business logic repeated across clients? If so, I don't like that.


I'll keep creating plain REST APIs for the time being. I haven't really faced any of the issues mentioned. Or at least they haven't impacted development time for me in a meaningful way.

If a client requires a GraphQL API, I'll happily learn. It does look like an interesting technology and a valid alternative.


I do like the idea of GraphQL, but even with it's problems, REST can be much simpler to understand/use https://www.slideshare.net/landlessness/teach-a-dog-to-rest


Why not just expose SQL? Only half kidding. I mean, you can set permissions and everything.


I am yet to see a proper easy production-ready GraphQL setup.

Lots of "hello world" stuff out there.

Throw in the requirements of a real SaaS and everyone shrugs.


GraphQL only solves half the problem, how do you update resources with GraphQL?


GraphQL supports both queries to access data and _mutations_ to change data:

  mutation {
    createUser(u: "user", p: "pass") {
      u,
      p
    }
  }


That's actually awesome, thanks for pointing that out!


and in addition to mutations (which mutate data stored in the backend) you can use subscriptions to update your local data store once they changed


By using mutations.


Playful title, but not to be taken literally


Yeah come on now seriously.

Also XML is cool. Not so sure about JSON.


GraphQL is vaporware. React's success took over Facebook Engineering's mindset.




Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: