55 comments

[ 3.3 ms ] story [ 152 ms ] thread
Obviously a basic example with one type of entity(user) makes it look the same but GraphQL's power is in being able to create whatever view of the data you want from the client and also being able to traverse the data's relationships IE User to Posts explicitly at the API consumption layer.
Nice! We actually generate our GraphQL Server by leveraging what our framework (which runs off Django Rest Framework) spits out in an OPTIONS request to a resource. We spruced it up a bit, but allows for dynamic creation of a server similar to this.
> REST and GraphQL really aren't that different.

As in: absolutely different, and GraphQL breaks nearly everything that makes REST REST.

Pretending it's not in the server-side code doesn't make it "not different".

REST is an interpreted standard for stateless transactions. How do you see GraphQL as breaking what makes REST REST? If you had said HATEOS, maybe there’s something there, but GraphQL does not fundamentally break the promises of a REST transaction as far as I can tell.
Good overview here: https://blog.goodapi.co/rest-vs-graphql-a-critical-review-5f...

Ok. It doesn't break all of REST's semantics and ideas. "Only" the entirety of 5.2.1 and and most of 5.3 in the dissertation

The author is declaring one approach to REST as the "one true way." Actually, I think the author is correct, ie pointing to a HATEOAS style REST approach. But the REST standard is interpreted. The article calls all of the RESTful APIs that are fragile in one way or another "so-called-REST." I kind of agree with that assessment of quality, but at the same time, they aren't "so-called-REST." They are actual REST. We can all just wish those were "so-called-REST" and that there was some additional mechanism to enforce "real" REST. As it stands, accusations of "that's not really REST" amount to being "No True Scotsman" arguments.
REST and GraphQL are in orthogonal domains and mutually compatible. This would be more obvious in the most common case for each where they are being used over HTTP if HTTP had generic (not specific to, e.g., WebDAV) safe method that took a request body with a representation of a query and returned a representation of the resource satisfying the query. [0]

GraphQL is basically just a generic resource representation for queries.

[0] Like the one proposed here: https://www.ietf.org/id/draft-snell-search-method-01.txt

This. GraphQL is agnostic to the application layer, whereas REST is tied to HTTP.

For instance, we have various REST-style endpoints that execute GQL queries directly on the backend.

REST is also transport-agnostic and definitely not tied to HTTP, even though that's by far the most common way in which it's used.
> This. GraphQL is agnostic to the application layer, whereas REST is tied to HTTP.

If anything it's the other way around really, HTTP is tied to REST, but even that would be a misnomer. HTTP is an implementation of the architectural style REST, and undoubtedly the most popular in terms of application. There are others though, such as CoAP for example.

But look at how the client consumes the APIs - it’s totally different.

Some funky abstraction over express.js server code looks similar for a trivial use case - that’s nice. But it’s ultimately nothing like REST under the hood.

My understanding looking at the code example is it turns a rest call into a services layer then maps it to GraphQL.

I think this creates a bad convention of creating a service layer dependency on express where it's not needed.

As a proof, I like the idea, but in design I don't like adding extra coupling where it's not needed.

One thing I do see that's missing (or maybe just not documented) is the power to specify the exact shape of the response.

One of the power of GraphQl is allowing us to specify how much or how little of the result objects we want. For example, a Blog post on a mobile app might just want only the short synopsis of the comments and the poster's name, while a web view might want the whole comment.

Interesting, I will agree that configuring an express server and GQL resolvers has a similar structure, in that they're composed of "routes" and "handlers" ("types" and "resolvers").

The biggest potential use case here would be to allow the server to expose a REST-style API as well as a GraphQL one with the same codebase - is that supported by this package? IMO it definitely should be.

The only other reason I can think of to use this is if you are used to writing express servers and don't want to change, which isn't a very good reason to use yet another package. graphql-tools makes writing the server pretty dead easy.

Seems like a great way to start out and experiment with a GraphQL API. It just seems like it would miss a lot of GraphQL features.
app.get('/users', (req, res) => {

app.get('/user', (req, res) => {

app.post('/createUser', (req, res) => {

These aren't what I'd consider to be RESTful... these seem more like traditional RPC calls.

I haven't done much JS, but what does this mean "this.post = this.put = this.delete = this.patch = this.query = this.mutation = this.get;" in Router Constructor.
Not sure if it answers your whole question but it means that the value of this.get gets assigned to all the other variables.
Makes sense, but why do we have to do it this way, assigning just get func to all other verbs (functions), cos this is an example?
It turns six lines into one line.

It looks impressive in software interviews, but I don't really see the use in it for production code. Not every JS dev immediately knows what's going on with this syntax.

The "=" operator always returns the value on the right side, and it always processes the right side before the left side.

Therefore:

1 - this.mutation = this.get // returns this.get

2 - this.query = <return value of this.mutation = this.get, which is this.get>

3 - this.patch = <return value of this.query = this.mutation = this.get, which is this.get>

n - and so on...

Essentially, it's setting 6 different properties all to the same value.

---

EDIT: Here's the same concept, but in a different context...

function fibonacci(num, memo = {}) {

    if (num <= 1) return 1;

    if (memo[num]) return memo[num];

    return memo[num] = fibonacci(num - 1, memo) + fibonacci(num - 2, memo);
}

On the return line, the right-to-left property of "=" forces the extreme right to be processed first. It returns the recursive call.

Then, the return value of this recursive call gets saved to "memo[num]".

Finally, the return value of "memo[num] = fibonacci(...) + fibonacci(...)", which is still the same return value from the recursive call, gets saved to the function return.

Thanks for taking time to put an example. I am familiar with the assignment rule, but this is a refresher. My question was more on why it was one function being used for all others.
Ah, well, could be useful for someone else who looks at it.
The reason you'd do this is because you are probably planning to return the same response for all the HTTP verbs.

Like if you wanted to return a empty hash {} for:

  GET /
  DELETE /
  PUT /
  PATCH /
  POST /
I guess just being lazy.
Click bait title. They really are quite different in very significant ways and not exactly comparable. For example GraphQL APIs allow for ad hoc querying of multiple resources and have a typed query language. Not that RESTful APIs can't do the same, but that's why they aren't really comparable. Interesting wrapper nonetheless.
Adhoc querying of multiple resources and REST are not incompatible, see e.g. oData. It basically offers the same functionality as GraphQL, but also follows all the Restfull http best practices.

You can see some oData examples here: https://www.odata.org/getting-started/basic-tutorial/#reques...

> Adhoc querying of multiple resources and REST are not incompatible, see e.g. oData.

This.

Sometimes I wonder if graphql proponents either are unaware of established REST strategies and tooling or if they intentionally turn a blind eye .

In terms of ease of building a query (and resulting ease of comprehension of that query) that will give you the exact response structure you want from the client-side, the two are not comparable, there is no blind-eye turning in this regard as far as I can tell.

But I'd love to see an REST-based GraphiQL equivalent to prove this wrong: https://github.com/graphql/graphiql

AFAIK, oData only lets you request a single entity type at a time, doesn't it? For example, in the example you provided, would it be possible to fetch a collection of People and Airports as part of the same request? What would that request look like?
No, you can batch requests.
The question was not about batching, it was about join queries over more than one resource type.
I guess I should be more clear...

batch means you can do things like combine these:

GET /serviceRoot/Airports GET /serviceRoot/People

into one request (and get the results in one response)

I believe that's what the poster was asking.

Here's a link to a different example from the OData site: https://www.odata.org/getting-started/advanced-tutorial/#bat...

You're using the word "join". I'm not sure if you meant that in a relational sense or not. If yes, then maybe you're wondering if you can get airports with their related people, or people with their related airports in one request with OData. Again, the answer is yes.

Thanks for the explanation!
No problem... I realize my initial answer was pretty useless. "batch" has a specific meaning in Odata but of course you wouldn't know that unless you already knew Odata.
No, you can query a collection of these entities and get back the resulting set with pagination.
That's REST + oData, not REST. GraphQL includes adhoc querying in the standard.

Otherwise I could claim ISAM is just like a SQL database because MySQL is a SQL database built on top of ISAM.

No, not REST + oData. oData is an http protocol which conforms to all of the REST best practices (url is identifier of a resource, use of http operations, use of http error codes, providing links to other resource, payload contains a representation of state).
REST is a broad term - there's nothing to stop REST apis from doing all those things with HATEOAS, discoverable apis, json schemas, etc. The real advantage of GraphQL is the distillation and combination of preexisting ideas into a coherent spec and toolchain with a mainstream advocate, rather than a loose collection of standards, conventions, and libs with no mainstream advocacy.

To be fair, I feel like this fact means GraphQL does sit at a higher level of abstraction than "vanilla REST", which does make them not-so-comparable.

> REST is a broad term - there's nothing to stop REST apis from doing all those things with HATEOAS, discoverable apis, json schemas, etc.

This fact should be emphasized. REST is just an architectural style, and it's absurd to claim that an architectural style bars developers from implementing specific functionalities.

It's even more absurd to compare a very specific implementation of a specific interface with an architectural style used to design and implement interfaces.

It seems to me that this whole GraphQL vs REST debate has absolutely nothing to do with REST or even HTTP APIs, and is actually a discussion about how reusing a ready-made solution developed by third-parties has some advantages over having to roll your own.

When I pitched GraphQL to the boss one of the selling points was, "and if we ever need to in a couple of days we could add a full REST API backed by GraphQL." But now she's addicted to playing with it in GraphiQL and gets it, and is evangelizing it to clients. In the end it's what the clients want that matters, and so far we're getting more disorientation from them than pushback.

It looks like we'll need to give clients more support in manipulating JSON, conversion to tabular data and help with pagination. There's a business opportunity for apps that help non-coders deal with GraphQL queries and results.

There's a lot more to be said about a schema-based API. On the server (which this project covers), maybe it's not as important, but it is tremendously helpful on the front end, especially when your data has a lot of relationships (Of course, you can do this without GraphQL). I think this is a big factor in how libraries like Apollo were able to grow so quickly.

It's also nice that it's more standardized than a REST API - I know that if I need to work with a GraphQL api, I can look at the schema and immediately know how all the pieces fit together and how to get what I need.

Except when they are. I was just implementing an endpoint that returns Reddit like comment data (replies nested in replies) and I quickly realized you can't pull this off in graphql because the return structure has to be predefined and static.

Ended up implementing it in REST.

Really? It’s called GraphQL and its schema can’t describe a simple tree?
The schema certainly can, but GraphQL queries have the valuable (in many but not all contexts) property that the response structure mirrors the request structure. If your request is nested no deeper than four scopes, then the response will also be nested no deeper than four scopes.
A GraphQL schema can easily define a tree but AFAIK the client must specify the desired recursion depth on that tree. This kind-of makes sense for the same reason that paginating list resources makes sense, but I can see how it would be annoying.
Aside from the fact you can return JSON types as a catch all.

It is possible to imbed types within types in GraphQL I.e.

Post {

Comments {

   Comments

  }

}
I read on Twitter that 2019 will be the year of resolver centered GraphQL frameworks (in difference to the schema based solutions). That approach should be more aligned with REST.
I'm not going to say that GraphQL is bad today, but

If it returns error messages with a 200 OK status, then it's not restful at all ( https://github.com/graphql/graphiql/issues/88 )

Isn't that specific to graphiql rather than GraphQL itself? From reading the issue it seems graphiql is expecting it in that format, and the actual status code to return is down to the developer.
Isn't that easy to do with REST as well however?
An error with a 200 OK status code is pretty clearly not what you _should_ do in REST.
No doubt, that's bad design. However, if you try-catch the code and return a custom error message, many frameworks would return a 200 by default if you don't explicitly set the status code.