REST limits my knowledge only to the primary key of the relationship.
Given a trivial question like "here's a user, I need her friends and their countries of birth" and the REST answer is a separate endpoint or an O(n) operation on the client because these are _separate resources_. You want the country flag too? I'm sorry, I can't support that requirement.
With GraphQL, it's -
user(handle: "daliwali") {
name,
friends {
country {
name, population, flag
}
}
}
No separate endpoint. You want to show to the client how many dogs those friends have, and if any of them play frisbee? No problems, and no backend engineers involved.
This is why I said REST is a key-value protocol like in redis. With redis you can either embed a small objects (which is not a relationship) or keep a PK of the relationships (which means many queries). The more consumers your API has, and the higher the latency, the more expensive either of those choices becomes.
You are correct that in a REST system, every resource has a "primary key", that is the URL.
Where you are wrong is that REST doesn't mandate that a resource can only be accessed by its "primary key". There is nothing stopping me from requesting the following URL:
GET /users/daliwali?fields=name&include=friends,friends.country
Any client would be able to follow that link and get something out of it, whether it's JSON or HTML, without needing specialized tooling such as a GraphQL client. A hyperlink makes that query widely accessible and interoperable with any HTTP client.
We're reasoning about a simple case, however. GraphQL is recursive, and HTTP parameters are generally not. You can use them to wrap a recursive language, but at that point you're just using the URL as a transport layer for the recursive language, and if the language is expressive enough it won't fit in a GETtable URL anyway... Past a threshold of complexity, you get into wanting that GraphQL client.
In reply to fixermark, there is also nothing stopping you from very complicated queries in REST. There is not even a requirement that the server must respond immediately. For example I could request:
POST /queries
With some raw database query as the payload (please don't actually do this) and the server could respond with HTTP 202 Accepted, meaning that it's going to take some time to process, meanwhile check back at the URL in the Location header when it's finished.
REST does not mandate any upper bound on complexity, that's up to you to decide.
> In reply to fixermark, there is also nothing stopping you from very complicated queries in REST.
What I believe others are getting at is that those complicated queries themselves need to be expressed somehow even within a REST request. GraphQL provides a convenient mechanism for doing so.
In theory you can even do GraphQL RESTfully, with each REST endpoint exposing its own schema. But in doing so it quickly becomes apparent that it would be easier just to forego REST conventions and expose a single consolidated schema.
Speaking for my own GraphQL experiences, on one project we had a GraphQL query generating reports that was around 50 lines long, with half a dozen fragments. Flattened out to match the approaches you've suggested for POST data and GET params it would have been hundreds of attributes. It's unclear that there's any open standard that would have provided as simple of a solution for expressing and executing those requests.
But at this point, it's so different and you've added so much work to it, I doubt anyone would recognize it as originally REST. You're basically rewriting GraphQL yourself. And sure, you're allowed to do that, but why?
>it's so different and you've added so much work to it
With web pages, it's standard and effortlessly handled by the browser. Given a form with inputs specified by the server, a client sends a request with media type application/x-www-form-urlencoded or multipart/form-data. There is a vast number of implementations for practically every language and platform. A machine client can send a form too, or JSON for that matter.
You have it backwards, Facebook is attempting to rewrite web standards by themselves. And that is undermining the open web.
> Given a trivial question like "here's a user, I need her friends and their countries of birth" and the REST answer is a separate endpoint or an O(n) operation on the client because these are _separate resources_.
Actually, I think that the answer following the REST architectural style, using HTTP, and not resorting to a custom HTTP method (which, actually, consistent with the REST architectural style would arguably be justified in this case), the correct approach would be to POST a representation of a resource representing the query to an appropriate query endpoint (which could be the user endpoint for queries specific to that user, since the query could reasonably be seen as a subordinate entity to the user to which it applied), and then GET the result of that query.
(In fact, the given GraphQL could well be the representation of the query.)
Ideally, HTTP needs a generalized safe method (like GET) that takes a payload (like POST) named something like SEARCH (there are HTTP-based technologies with domain-specific versions of this, but no generally accepted representation-neutral version) so that this can be, when the server architecture supports synchronous exchanges, a one-round-trip process.
> This is why I said REST is a key-value protocol like in redis.
But this is simply false. Its trivial to make key-value protocols that follow REST (especially the REST-minus-HATEOAS that is common these days), but REST isn't limited to that, or even specialized to it.
Given a trivial question like "here's a user, I need her friends and their countries of birth" and the REST answer is a separate endpoint or an O(n) operation on the client because these are _separate resources_. You want the country flag too? I'm sorry, I can't support that requirement.
With GraphQL, it's -
No separate endpoint. You want to show to the client how many dogs those friends have, and if any of them play frisbee? No problems, and no backend engineers involved.This is why I said REST is a key-value protocol like in redis. With redis you can either embed a small objects (which is not a relationship) or keep a PK of the relationships (which means many queries). The more consumers your API has, and the higher the latency, the more expensive either of those choices becomes.