Hmm. From what I understand of GraphQL, it gives you: - less boilerplate (no need to create GET REST endpoints and corresponding JS AJAX calls) - consequently, more flexibility (just request more data in the client, no need to update server code) - formalized query language (and apparently, the ability to check it?) However, the idea of exposing your schema to arbitrary requests sounds much too dangerous to me. I see…
This seems to be a common misconception. GraphQL is just a protocol; query fields don't have to be tied to your schema at all, so you don't have to expose anything you don't want to, in the same way that you don't have to make every table accessible via REST.
From REST to GraphQL
21–30 of 46 posts
Re: From REST to GraphQL
#22Hmm. From what I understand of GraphQL, it gives you: - less boilerplate (no need to create GET REST endpoints and corresponding JS AJAX calls) - consequently, more flexibility (just request more data in the client, no need to update server code) - formalized query language (and apparently, the ability to check it?) However, the idea of exposing your schema to arbitrary requests sounds much too dangerous to me. I see…
This seems to be a common misconception. GraphQL is just a protocol; query fields don't have to be tied to your schema at all, so you don't have to expose anything you don't want to, in the same way that you don't have to make every table accessible via REST.
The article mentions pre-processing the graph to determine complexity, some caching, and some timeouts. This is not good enough and can/will be worked around. Inflexible API's with (mostly) single, predictable paths to data provide a great way to tailor performance at the (IMO) negligible cost of extra HTTP requests.
Re: From REST to GraphQL
#23Another possible solution while sticking to REST: instead of embedding all the sub-objects have an "expand" query param where you can list all the sub-objects/relationships you'd like returned (EG: GET /playlists/ID?expand=tags,tracks) This way you can still do everything in one request but not bloat the response data structure for situations that don't need the sub-objects.
Re: From REST to GraphQL
#24Another possible solution while sticking to REST: instead of embedding all the sub-objects have an "expand" query param where you can list all the sub-objects/relationships you'd like returned (EG: GET /playlists/ID?expand=tags,tracks) This way you can still do everything in one request but not bloat the response data structure for situations that don't need the sub-objects.
GraphQL is the natural extension of that, but more flexible and composable. I can get a user's name and email, and his friends names, with the cost of only one request and latency.
You could change your REST API to do the same, but eventually you are reproducing the GraphQL equivalent.
Re: From REST to GraphQL
#25It's great that GraphQL's solved some of your issues, and you've encouraged me to look into it a bit more. One thing you should worry about, though - if at any point there's any user-specific data in an HTTP response that doesn't have the user's ID in the URL (or something pointed to by the 'vary' header), it kills the idempotence of the request, whether you're using what Rails gives you or GraphQL or XML-RPC or what…
(For one, your queries can be large so are POSTed anyway.)
Relay is a caching layer that understands GraphQL semantics, but you no longer have transparent HTTP proxies, browser caching, etc. Though HTTP proxies are dead thanks to HTTPS, and with modern browser APIs, you can do your own limited caching.
It's certainly a tradeoff for what you expect to give you best performance gains: fewer roundtrips, or more caching by third parties.
Re: From REST to GraphQL
#26In addition, in reading the thing that "pushed you over the edge" ... I really don't see how REST has failed you here, in terms of how you are partitioning your data. I can't imagine that some kind of intelligent caching of data (no need to re-download playlist data to the client that hasn't changed, etc). wouldn't have been a more straightforward approach here.
I find the GraphQL stuff interesting but your problems would have been better served by refactoring what you had rather than moving to a completely new API and query format, at the cost of sacrificing an easy to use interface for your internal and (maybe) external consumers of your API. I'm not convinced you won't have the same issues with GraphQL and could stand a bit more pragmatism.
Re: From REST to GraphQL
#27Re: From REST to GraphQL
#28When I first saw GraphQL, my thought was that it was a nice abstraction to enable client-dependent API. But it lacks the actual implementation, and provide no answer to "what about performance?" question.
DataLoader answer that question elegantly.
Re: From REST to GraphQL
#29It's great that GraphQL's solved some of your issues, and you've encouraged me to look into it a bit more. One thing you should worry about, though - if at any point there's any user-specific data in an HTTP response that doesn't have the user's ID in the URL (or something pointed to by the 'vary' header), it kills the idempotence of the request, whether you're using what Rails gives you or GraphQL or XML-RPC or what…
That's correct, you destroy HTTP-level caching. (For one, your queries can be large so are POSTed anyway.) Relay is a caching layer that understands GraphQL semantics, but you no longer have transparent HTTP proxies, browser caching, etc. Though HTTP proxies are dead thanks to HTTPS, and with modern browser APIs, you can do your own limited caching. It's certainly a tradeoff for what you expect to give you best perfo…
Well, they're not as broadly useful as without HTTPS, but you can still always MITM yourself to get a free transparent caching layer between the client and your end server.
Re: From REST to GraphQL
#30Another possible solution while sticking to REST: instead of embedding all the sub-objects have an "expand" query param where you can list all the sub-objects/relationships you'd like returned (EG: GET /playlists/ID?expand=tags,tracks) This way you can still do everything in one request but not bloat the response data structure for situations that don't need the sub-objects.
{
playlist(id: 123) {
tags,
tracks(top: 5)
}
}