4 ms·
(Author of the post here) Thanks for the notes! > And immediately after that the article spends two pages of text explaining how insanely complex the "becomes
by djmashko2 9y ago
(Author of the post here)
Thanks for the notes!
> And immediately after that the article spends two pages of text explaining how insanely complex the "becomes easy with GraphQL" really is, and offers no actual details on the "easy" part.
Hi, thanks for this piece of feedback! I could have done a better job here, since I was summarizing a 38 min talk into a few paragraphs.
These parts are actually talking about different concepts:
The first is about ensuring that a single fetch from the UI knows about all the data it needs, so you can easily avoid multiple roundtrips to the database. This is something you can do with a basic in-process caching tool called DataLoader: https://github.com/facebook/dataloader https://github.com/facebook/dataloader
The second is about caching _across_ requests, something that people usually have special infrastructure for in REST, such as Varnish. This talk was elaborating on how a GraphQL-specific piece of caching infrastructure might work, and sit in exactly the same place as REST caching.
> Oh, your client has to be cache aware.
I think the intention was to say that it _could_ be cache aware. It doesn't need to be, but you end up with a really nice situation.
> I would love to see an explanation how GraphQL makes caching for this easy.
My intention here was to say that GraphQL's ability to understand what fields are being asked for makes it easy to return specific cache controls, rather than having to put one on the whole query. So your server basically generates the control for you (this is something that exists today)
> It's called REST APIs and we've known how to do them since 2001.
I don't think REST has a way to automatically combine multiple REST services, and then query them all in one HTTP request without multiple roundtrips to the client, which was the goal here.
Happy to talk more, and thank you for bringing up some of the places where I can communicate more clearly in the future! The audience of the talk was a GraphQL conference, but I should definitely consider next time that people who aren't already bought into the idea of GraphQL will be taking a look as well.
- dmitriid 9y ago> a single fetch from the UI knows about all the data it needs, so you can easily avoid multiple roundtrips to the database. This needs to be backed up by data. In my opinion there's no difference between GET /users/1 GET /users/1/friends and { user(id: 1) { name age friends { name } } } Unless the backend is extremely smart and can generate (optimized!) SQL queries on the fly from GraphQL schemas, this will be two trips to the database. Granted, there's LINQ and some ORMs where you just chain requests. And still... And the above can also be solved by providing an `Accept: application/vnd.my-company.users-full+json` in REST. > My intention here was to say that GraphQL's ability to understand what fields are being asked for makes it easy to return specific cache controls, rather than having to put one on the whole query. How? Skimmed through the video. Oh. Right. By providing custom `maxAge` fields to the returned data so that a custom-built gateway (that has to be schema-aware) could build a cache of that data. An exact same thing can be done in REST: add custom fields, develop a custom resolver/caching layer, voila. There is a reason no one is doing that :)
- AzzieElbab 9y agobut even in your example, you already made 2 rest requests as opposed to 1 via graphql. What if your scenario is to GET all friends whose names start with D of friends of a friend ?
- dmitriid 9y ago> but even in your example, you already made 2 rest requests as opposed to 1 via graphql. You can easily mitigate that with something like: GET /user/1 Accept: application/vnd.my.user-full+json Where the server will return full data if the client sends `application/vnd.my.users-full` Accept header > What if your scenario is to GET all friends whose names start with D of friends of a friend ? I really wonder what your scenario would be on the server for this request in GraphQL For REST you would look at actual use cases and design for that. Most likely something like GET /user/1?filter=friends&by=D Accept: application/vnd.my.user-full+json GET /user/1/fof Accept: application/vnd.my.user-full+json
- AzzieElbab 9y agowhy "mitigate" anything when you are given a language specifically designed to describe and solve these types of problems? Of course, you can create a custom end-point for any type of request. The point is, you do not really have to. Also, as far as scenarios in the real world go, traversing some kind of graph is practically everyday kind of thing, from structured organizations to billing to who follows a guy who liked some tweet to things like snomed
- dmitriid 9y ago> given a language specifically designed to describe and solve these types of problems It's not a first language "specifically designed" and not the last. It is a language designed to solve Facebook's problems. Do you have Facebook's problems? I highly doubt it :) Meanwhile there are multiple questions that are left unanswered in all the "GraphQL is amazing" articles: - caching. Where is it? How do you do it? Official docs on caching are laughable at best [1] - data access. With ad-hoc queries how do you make sure the right people get the right data? GraphQL docs on that are equally laughable [2] - how do you make sure the server doesn't buckle under ad-hoc uncacheable queries where auth is solved by "passing a fully-hydrated object instead of an opaque token or API key to your business logic layer". Oh, hey, if you rely on microservices, and you need to return only a subset of data for the query, how do you do that? Remember, all queries are ad-hoc. There are definitely more issues than the ones right off the top of my head. Such as "data collocation", "mutations are guaranteed to execute sequentially" etc. [1] http://graphql.org/learn/caching/ http://graphql.org/learn/caching/ [2] http://graphql.org/learn/authorization/ http://graphql.org/learn/authorization/
- dmitriid 9y ago> My intention here was to say that GraphQL's ability to understand what fields are being asked for makes it easy to return specific cache controls, rather than having to put one on the whole query. To be more specific: "the entire query" in REST (or, really, in any HTTP-request) can be cached, alongside with all its data on multiple levels of the existing infrastructure with nearly no extra configuration. Cache-Control, ETags, Vary etc. Most proxies don't even have to parse the query or the response to handle caching in this manner. Match headers, boom, you're done. With proper headers the request might not even leave a user's computer. GraphQL on the other hand: - eschews cacheable requests. Everything is a non-cacheable POST - the "caching becomes easy with GraphQL" in reality becomes a custom caching server that has to parse both the request and the response for each request to find which fields are requested, and match them against whatever's in the cache. - Actual quote from the video: "add cache-control to your data" ... "and all you proxy or your gateway has to do is interpret your data". WAT. The only time an API gateway should interpret data is when we're transparently upgrading calls from v1 to v2 and back :)