Live data from Hacker News

The GraphQL stack: How everything fits together

dev-blog.apollodata.com

71–80 of 116 posts

Re: The GraphQL stack: How everything fits together

#71

GraphQL is above all, just an optimization. It optimizes the amount of bytes sent over the network. I'm very happy with REST APIs (maturity level 2/3) and see no reason to change as we've never had performance issues. Most companies are not Facebook with 1 billion customers. The fact that clients can compose their own queries brings nothing new, as you still have to allow these capabilities on your server, just like…

(Author of the post here) > GraphQL is above all, just an optimization. It optimizes the amount of bytes sent over the network. This was a common thought when GraphQL was first announced, but working with organizations that are adopting it we've found just the opposite: It's actually the tooling and development velocity benefits that people get the most value of. It's kind of like if you could design your API to be s…

Thanks for your reply. I've not ditched graphQL forever, but there's a lot of buy-in involved for what it could give me right now. The tech is quite intrusive on your web server.

I didn't know people using redux also cached responses forever, that seems beyond naive to me :)

Re: The GraphQL stack: How everything fits together

#72

> GraphQL knows all of the data requirements for a UI component up front, enabling new types of server functionality. For example, batching and caching underlying API calls within a single query becomes easy with GraphQL. 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. Oh, your c…

(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 differ…

> 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 :)

Re: The GraphQL stack: How everything fits together

#73

My main concern with GraphQL is access control. What happens if the user doesn't have access to part of the requested data (a subtree)... Will the GraphQL engine return an incomplete result, an inline error or will the whole query fail? What if you only want to allow showing specific fields of a resource; for example when a user requests for another user's account details, we need a way to block them from getting cer…

We let our GraphQL server accept a JWT authorization header, which is then propagated to all service calls it does. When the user doesn't have permission to some (sub)resources being requested, the GraphQL server doesn't see it either.

But what comes back?

Lets say I request a user, his name, email and all their friends.

But I don't have access to the friends.

Now do I get nothing back and the error that my request would include data I have no access to?

Or would I get name and email, but the list of friends would be empty? would I get an additional warning somewhere so I know it's an permission problem and the user doesn't have no friends?

Would I get an inline error in the place of the friends?

Re: The GraphQL stack: How everything fits together

#74

I'm an admitted dumbo about this stuff. Here's what it looked like from that point of view: Hey cool, a new nice looking common query language that can do neat composition of results. Perfect, I've been wanting to break free of the SQL box since forever. Wait, what? You have to write SQL queries for everything still? So you define types, and have to write SQL queries for those types, and graphQL gives you some compos…

You're in luck, there are libraries that can do it for you! https://github.com/stems/join-monster And even a system that generates your whole schema: https://github.com/postgraphql/postgraphql Plus, the Graphcool framework allows you to bring your own DB: https://github.com/graphcool/framework

Holy crap, that's awesome, thanks!

Re: The GraphQL stack: How everything fits together

#75
post #73

Earlier quoted context omitted.

We let our GraphQL server accept a JWT authorization header, which is then propagated to all service calls it does. When the user doesn't have permission to some (sub)resources being requested, the GraphQL server doesn't see it either.

But what comes back? Lets say I request a user, his name, email and all their friends. But I don't have access to the friends. Now do I get nothing back and the error that my request would include data I have no access to? Or would I get name and email, but the list of friends would be empty? would I get an additional warning somewhere so I know it's an permission problem and the user doesn't have no friends? Would I…

That's entirely up to you and how you choose to implement your fields' resolutions.

Re: The GraphQL stack: How everything fits together

#76
post #18

Can anybody explain to me how it's solving any problems? The way I see it they only move the responsibility to combine data from client to server. At the same time, you now don't just expose a couple of endpoints, you need to support a query language, which seems to impose much more effort in things like authorization. I admit I don't see the benefit.

I'm in the process of moving a large legacy Rails app to GraphQL. I'm able to deprecate massive amounts of code.

We currently have a massive number of view models, which are responsible for transforming models or collections of models into payloads for consumption by various client endpoints. Each payload method takes a whole suite of options to allow us to select this or that subset of fields, or to eager load this or that join. In the cases where we have heavily disparate payloads, we've ended up with parallel several implementations of "here's how to generate a JSON object". It's a giant mess - it's worked, but it's a mess.

GQL completely eliminates all of that. Each payload specific to each view is now specifically enumerated via a GQL query. We basically took all our individual field helpers out of the view models and implemented our GQL field resolutions with them - the actual translation work was minimal.

The end result is that a) we have massively less code developing payloads and b) we aren't overdelivering massive amounts of JSON to client endpoints because implementation X happened to be a superset of the data that we wanted. It also solves the problem of "slow bloat" - you implement a #to_json for one view, use it, and later another view uses this, but needs to add an extra field. Now both views retrieve that extra field. Repeat this process over 5 years and multiple consuming views and you have gigantic payloads which are mostly wasted in any individual context.

We even still support our legacy REST API with this system - the app can act as a GQL client, making a query and then emitting the response as JSON. Our REST API is now just one specific, brittle subset of our GQL functionality.

As soon as you find yourself wanting to customize your data serialization per view/endpoint, GQL becomes extremely useful.

Re: The GraphQL stack: How everything fits together

#77

Earlier quoted context omitted.

> It's called REST APIs and we've known how to do them since 2001. The aim of GraphQL insofar as I understand it is that instead of having to develop two things (a front-end and a back-end REST API that talks to your database or other services), you need just one (a front-end that talks to GraphQL). Mind you, graphQL becomes the back-end-for-front-end then, and will still need a lot of work. The main point is that wi…

> you'll only need one for all of your apps, So where are my clients for statically typed languages? I looked into GraphQL and promptly dropped it cause I couldn't seem to call into it from Java in any sensible way. If all your "apps" are javascript, maybe this is true, but that hardly makes it a universal technology.

It could have better documentation but here's the Java client for Android: https://github.com/apollographql/apollo-android There's also a Swift client available: https://www.apollographql.com/docs/ios/

Re: The GraphQL stack: How everything fits together

#78
post #42
post #36

Earlier quoted context omitted.

>, you now don't just expose a couple of endpoints, you need to support a query language, Here's how I think of it. (Others can correct or elaborate my understanding.) Let's say you have 1 REST endpoint such as "xyz.com/customerlist" to return a JSON response and behind the implementation is a SQL "SELECT ∗ FROM T" and you get back a 100k response with all rows and all columns. You really only wanted customer's name…

What if you had one one endpoint called xyz.com/sqlquery and you would just send it a SQL Query in the form a string, the server would validate it and authorize it and return the data or reject the request. Is that different than GraphQL?

The difference is that GraphQL was designed to be used like that, so it is relatively easy to limit what capabilities the client can use. SQL was not designed to be used like that, so for complex queries it will be very difficult to verify that the client isn't doing something that it isn't allowed to do.

Re: The GraphQL stack: How everything fits together

#79
post #50
post #47

Earlier quoted context omitted.

The solution for authorization/access control is to use "Dataloader" [1] which is also made by Facebook. You write a single source of truth for how authorization is handled, and make sure that graphql resolves with this source. Dataloader is not as well known as GraphQL, but crucial for complex authorization systems imo. It also has a bunch of other features like batching and caching which makes your life easier when…

I've only ever seen DataLoader used for batching database queries, how do you create a single source of truth for authorization with it? Do you have a code snippet somewhere?

Check out this article [1] (or video) on Dan Schafer's talk, on how they use Dataloader and GraphQL internally at Facebook. Covers most of it.

To summarize, they create a class for each GraphQLType which has their own "gen" function such that it is the only way to generate data. This way you get a single source of truth.

There's also a video of Lee Byron going through Dataloader's source code which was pretty fun to watch.

[1]: https://dev-blog.apollodata.com/graphql-at-facebook-by-dan-s...

Post reply on HN