News for hackers. Stuff that matters.
Re:Migrating to GraphQL: A Practical Assessment by rocmcd on Thursday July 04, 2019 @04:04PM (#20357317)
I don't think there's any surprise that GraphQL reduces the size of the responses compared to typical REST (excluding things like JSON:API). If that's the measurement that's most important, then it seems GraphQL is the obvious choice.

For myself, the 'practicality' of GraphQL would be more on complexity of the implementation, training of engineers, potential re-implementation of client logic, ease and depth of debugging, performance, etc. It seems these days that the size of the response is not typically a limiting factor in most applications I've interfaced with (though maybe I've never been exposed to that world before).

Can anyone speak to how a migration from REST to a GraphQL went? My biggest concern is around the complexity of the thing. It just seems so much more complex than REST, but maybe I haven't spent enough time with it.

Re:Migrating to GraphQL: A Practical Assessment by lwansbrough on Thursday July 04, 2019 @05:38PM (#20358017)
We migrated from RESTful HTTP to GraphQL and then back to RESTful HTTP. GraphQL is cool, but actually maintaining it is a nightmare and I think it would be rare for the end product to turn out better. Here's a few of the cons for us:

- GraphQL parsing and interpretation is considerably slower than RESTful JSON. I'm talking an order of magnitude difference in .NET Core.

- The required POSTs cannot easily be (if at all?) cached by caching services such as Cloudflare

- It's more work to have to define what data you want than to just spit out the data that's available. Having to continually update your client side queries in order to fetch all the available data is tedious as hell. The whole over/underfetching argument is not worth the incurred performance hit nor the bandwidth improvements.

- GraphQL promotes laziness about documentation because it's "self-documenting" -- turns out most API users still struggle to understand how it works and need better API guides anyway, so the reflection is largely useless (it's about as good as those auto-generated Java docs you find on Oracle's website.)

- Users get RESTful. They know it, it's not a toy, and it just works. I'll repeat this again because Silicon Valley doesn't seem to get it: GraphQL is not user friendly.

Re:Migrating to GraphQL: A Practical Assessment by atombender on Thursday July 04, 2019 @09:34PM (#20359262)
> The required POSTs cannot be easily (if at all?) cached

GraphQL allows queries to be performed with GET:

  http://example.com/graphql?query=query{user{id}}
You want to use POST for mutations, but read queries can be run through GET and cached just like REST. There's literally no difference -- it's HTTP, after all.
Re:Migrating to GraphQL: A Practical Assessment by lwansbrough on Thursday July 04, 2019 @11:20PM (#20359577)
There is a difference. When "everybody" has a unique query, there's no cache.
Re:Migrating to GraphQL: A Practical Assessment by alexchamberlain on Friday July 05, 2019 @02:42AM (#20360358)
In practice, doesn't everyone run the same query in Production? If variables are being used, they're the same degrees of freedom that rest had anyway, right?
Re:Migrating to GraphQL: A Practical Assessment by underwater on Friday July 05, 2019 @07:22AM (#20361635)
Akamai can certainly cache POST request based on the body of the requesr. And persisted queries can be added as a caching solution on top of GraphQL.
Re:Migrating to GraphQL: A Practical Assessment by sgift on Friday July 05, 2019 @04:50AM (#20360905)
> GraphQL parsing and interpretation is considerably slower than RESTful JSON. I'm talking an order of magnitude difference in .NET Core.

Looks like an implementation problem. I couldn't measure a significant difference between both for comparable requests in Java. Also, parsing/interpretation is almost never the bottleneck of an application.

> It's more work to have to define what data you want than to just spit out the data that's available. Having to continually update your client side queries in order to fetch all the available data is tedious as hell. The whole over/underfetching argument is not worth the incurred performance hit nor the bandwidth improvements.

"all the available data" is almost always an anti-pattern, so yes, this gets tedious. Frontends should have specific requirements what data they need and if you only request those data it isn't tedious at all + you don't waste any bandwith. This is the "select * from" school of sql all over again combined with "what do you mean we have more than one client with different requirements?" - now you either always send the superset or start an ad-hoc implementation of what GraphQL provides you to only send the required data to each client.

> GraphQL promotes laziness about documentation because it's "self-documenting" -- turns out most API users still struggle to understand how it works and need better API guides anyway, so the reflection is largely useless (it's about as good as those auto-generated Java docs you find on Oracle's website.)

GraphQL self-documentation and exploration are sufficient if whoever uses the API understands the domain model underlying it. You will always have to teach people the domain model, but after they've understood this people can use self-exploration to find what they need in that model.

With REST APIs you have to document the domain model and then painstakingly each and every technical API endpoint, cause domain model and technical API always differ (usually even two endpoints of APIs cannot be called in the same fashion - what do you mean the parameter here is called maxResults now? It was called maxCount over there!)

> Users get RESTful. They know it, it's not a toy, and it just works. I'll repeat this again because Silicon Valley doesn't seem to get it: GraphQL is not user friendly.

No, they don't. They have learned to accept that companies only provide them REST and they have to live with it, even if it is bad. SOAP or GraphQL are both (in different ways) vastly superior, but one has fallen out of fashion and the other one is seen by some of the "REST is great" people as a toy, cause they think REST is some kind of holy grail.

Disclaimer: Does GraphQL solve all your problems? No. Nothing does, you will have to do it yourself, that's part of your job.

Re:Migrating to GraphQL: A Practical Assessment by lwansbrough on Friday July 05, 2019 @06:41PM (#20366468)
> Looks like an implementation problem. I couldn't measure a significant difference between both for comparable requests in Java. Also, parsing/interpretation is almost never the bottleneck of an application.

That would depend on your definition of significant, and the complexity of the AST you're parsing. Obviously I'm talking about the implementation I have available to me, but GraphQL would routinely take 100+ms to return the same data that ASP.NET could deliver in 10ms or less. And this does indeed make sense as it is simply more overhead. The more likely cause of the difference is that it's just complicated to optimize GraphQL graph queries. When you have a single endpoint, you know exactly what data you need and a human can optimize around that specific requirement, whereas GraphQL attempts to fetch each piece of the graph in isolation (or not, if you optimize for that, which is additional work.)

> "all the available data" is almost always an anti-pattern, so yes, this gets tedious.

That's not really what I meant. What I meant was, in order to fetch the data I want for a specific task, I have to list all of it. Which is silly. I know what I need to return on the server side, why should I have to write it twice? This is especially cumbersome in the case of return a Dictionary<string, string> or whatever it might be, where the object keys can change over time.

> This is the "select * from" school of sql all over again combined with "what do you mean we have more than one client with different requirements?" - now you either always send the superset or start an ad-hoc implementation of what GraphQL provides you to only send the required data to each client.

Indeed, this is a real problem, but typically if all your data is mapped well you shouldn't run into this very often. Most people who are implementing GraphQL on their servers don't have this problem. They're doing it because it's cool. Problems like this are what versioning is supposed to cover. If you're having to constantly change your API for different clients however, your product is not the API itself. Most people are just trying to create an API that people can pick up and use easily.

> GraphQL self-documentation and exploration are sufficient if whoever uses the API understands the domain model underlying it. You will always have to teach people the domain model, but after they've understood this people can use self-exploration to find what they need in that model.

> With REST APIs you have to document the domain model and then painstakingly each and every technical API endpoint, cause domain model and technical API always differ (usually even two endpoints of APIs cannot be called in the same fashion - what do you mean the parameter here is called maxResults now? It was called maxCount over there!)

If you haven't explained the purpose for each endpoint (or queries/mutations as GraphQL calls them) then you haven't documented it. So you must "painstakingly" document each "endpoint" in either case. Your API docs should be guidance, not just "listTransactions(): This lists the transactions". This is exactly the kind of thing I'm talking about. At the very least, it's the same amount of work. The difference between not-GraphQL and GraphQL is with GraphQL you've probably set up GraphiQL and now your model attributions are no longer co-located with your real documentation!

> No, they don't. They have learned to accept that companies only provide them REST and they have to live with it, even if it is bad. SOAP or GraphQL are both (in different ways) vastly superior, but one has fallen out of fashion and the other one is seen by some of the "REST is great" people as a toy, cause they think REST is some kind of holy grail.

This is spoken like someone who hasn't actually worked with developers who have to implement this stuff. Users _in general_ are confused by GraphQL. Especially, of course, novice developers. They really don't know where to start with it. Real REST is not something people advocate for these days. All I'm talking about is, users are happy when you provide them with well thought out endpoints that each have their own URL and cover the use cases they have.

Imagine if Stripe had started with GraphQL. The number one question they'd have received would have been: "what do you mean I should install the GraphQL library so I can hit your APIs?". APIs work best when they're SIMPLE, and GraphQL is anything but simple.

Re:Migrating to GraphQL: A Practical Assessment by glacials on Thursday July 04, 2019 @04:44PM (#20357643)
It depends on your backend architecture. We migrated a microservices (Go) architecture to GraphQL and it gets very complex with a lot of boilerplate. Perhaps part of that is GraphQL's and its supporting libraries' infancy, but supporting the ability to ~infinitely nest objects in a microservices architecture at scale makes every field addition feel like building a gigafactory.

On the plus side GraphQL is very simple and adaptable for frontends. It just comes at the cost of moving so much complexity to the backend.

Re:Migrating to GraphQL: A Practical Assessment by fhennig on Thursday July 04, 2019 @10:34PM (#20359446)
I think it heavily depends on the server library for you language of choice. I've tried sangria for scala, graphql-java and graphene for python and all of them are quite different, and mostly badly documented, but I found the java implementation to be the easiest one to get started with.

Graphene seems like a nightmare but the documentation is improving and once you get used to the design it's actually not so bad and more feature complete than the others.

I think moving complexity to the backend is actually not such a bad idea, so the frontend can focus more on actually just displaying the information.

Re:Migrating to GraphQL: A Practical Assessment by git-pull on Friday July 05, 2019 @12:34AM (#20359862)
Using graphene at work.

Absolutely love graphql as a technology. The pagination and ability to structure a query to pull a lot of data is nice.

As for some of the other comments - it's true you can't just write any query: but you can always add new fields, lists, connections (basically a pagination-friendly list), etc against arbitrary things on the backend. It's your backend, you control what data you serve.

The graphql-python stack is layered like an onion (graphene on top, graphql-core inside). You will probably be doing something like flask-graphql or graphene-django on top of that.

There is a huge negative for python <-> graphql for us, and it's the error system and promises. Perhaps this is what graphql servers in JS are like, but graphql-core hijacks python's error system by wrapping fields in promises.

So graphql-core is acting very very true to graphql's implementation in node: to the point it creating a mountain of breadcrumbs in sentry.

It also overrides the "next" built-in and tries to emulate express-style callbacks. Another thing ported from node into python that doesn't translate well imo.

Aside from that though: graphene has been really speedy, fast to work with. Documentation is getting nicer. The developers on the issue tracker are very nice. And as a general graphql thing: https://github.com/graphql/graphiql is really nice!

And one more graphql thing: It's typed. In a big API, being able to lay out stuff like that goes a long way. We're generating typescript types via schema.graphql output, and response types via relay. In a real big frontend project, it pays off a lot.

I recommend giving graphql a shot.

Re:Migrating to GraphQL: A Practical Assessment by munk-a on Thursday July 04, 2019 @05:14PM (#20357861)
That was our assessment, some gained front-end speed at the cost of a loss of back-end performance and simplicity - we ended up staying with bespoke REST endpoints because they're cheap and do the job.
Re:Migrating to GraphQL: A Practical Assessment by dmitryminkovsky on Thursday July 04, 2019 @04:47PM (#20357654)
You can’t infinitely nest objects in GraphQL from the perspective of the query (a query can’t have self referring fragment, for example).
Re:Migrating to GraphQL: A Practical Assessment by jes5199 on Friday July 05, 2019 @12:28AM (#20359843)
I was at GitHub during their migration to GraphQL, and it was extremely expensive. But they had some weird ideas - there was a mandate to use GraphQL even to render server-side templates, which meant completely replacing the existing MVC architecture with a sort of fat-model DSL that implemented GraphQL resources. Of course, all of that DSL was developed in-house, so documentation was weak and it was impossible to debug...
Re:Migrating to GraphQL: A Practical Assessment by adamscybot on Thursday July 04, 2019 @04:44PM (#20357639)
I've found it reduces complexity in your app code (at least on the front end). You basically have no or extremely minimal data fetching logic where as with REST you often find yourself making more requests in response to other requests. I.e to traverse relations. GQL Gives you that for free.

Also the tooling is next level . GraphIql alone is miles ahead of any REST tooling offerings. Also, typescript generation. Truly improved my workflow.

Re:Migrating to GraphQL: A Practical Assessment by tepidandroid on Thursday July 04, 2019 @10:02PM (#20359361)
I find the lack of tooling the annoying part actually... the necessity for 3rd party frameworks like Apollo, tac-on modules like Dataloader... the lack of up-to-date, feature-parity server implementations besides the canonical Javascript version... etc.
Re:Migrating to GraphQL: A Practical Assessment by dmitryminkovsky on Thursday July 04, 2019 @04:41PM (#20357614)
What’s the complexity you’re thinking of? In my experience, GraphQL is so much simpler than REST. There’s a whole category of thinking you don’t have to engage in (is this POST? PUT?). And to start I wouldn’t migrate from REST. I’d wrap a REST service with GraphQL and take it from there.
Re:Migrating to GraphQL: A Practical Assessment by adamscybot on Thursday July 04, 2019 @04:47PM (#20357655)
That essentially means you are still overfetching underneath the hood but yeh -- for me the benefits are in its ergonomics anyway. The whole under/overfetch thing is overstated.
Re:Migrating to GraphQL: A Practical Assessment by dmitryminkovsky on Thursday July 04, 2019 @04:51PM (#20357680)
Locally, yes. But that’s not a big deal unless your network is that saturated. Also, with wrapping we’re just talking first steps. Anyway the overfetching thing is less about bandwidth and more about maintaining compatibility with older clients and knowing which clients require which fields. Since each GraphQL client explicitly states the fields it needs, it’s much easier to retire old fields.
Re:Migrating to GraphQL: A Practical Assessment by dmitriid on Friday July 05, 2019 @03:31AM (#20360548)
> There’s a whole category of thinking you don’t have to engage in (is this POST? PUT?)

There’s a reason that category of thinking exists. But since GraphQL libs are now busy implementing caching in top of non-cacheable POST requests, this argument is lost on them.

Re:Migrating to GraphQL: A Practical Assessment by dmitryminkovsky on Friday July 05, 2019 @02:53PM (#20364843)
> There’s a reason that category of thinking exists.

What's the reason?

> But since GraphQL libs are now busy implementing caching

What are you referring to? You mean like https://github.com/graphql/dataloader ?

> in top of non-cacheable POST requests, this argument is lost on them.

I think caching/serving HTTP results is a bad paradigm. It makes sense if you're serving HTML for a content site or something like that, but doesn't make sense when you're serving an API.

Re:Migrating to GraphQL: A Practical Assessment by mdaniel on Thursday July 04, 2019 @04:56PM (#20357720)
> It seems these days that the size of the response is not typically a limiting factor in most applications I've interfaced with

As a "for your consideration," optimizing for the _client's_ concerns might not the true win, but if the server-side were able to side-step some joins, it could be a win for the whole community since it could -- in theory -- make everyone's experience better. The ability to push conditionals on the server side _could_ side-step multiple round-trips, too: https://graphql.github.io/learn/queries/#directives

Just this morning I tried out GitHub's GraphQL interface, and it for sure requires some thinking to reframe the question in terms of the GraphQL surface-area they expose, but GraphQL also has built-in schema discovery, which is something one would typically have to read the docs to access.

It's tremendously annoying that one must package a GraphQL query _inside_ a JSON field named `query` versus the much more sane `curl --data-binary 'query MyQuery { some fields }' https://example.com/graphql` but it seems that packaging is required for separating variables from the actual query itself: https://graphql.github.io/learn/queries/#variables (although having two endpoints, `/graphql` and `/graphql.variables`, or switching behavior based on content-type, would be amazing and, at least in theory, very little server-side work)

Speaking of switching endpoints, the GraphQL community claims that the api is a lot more versioned, too, getting one out of the business of `/v1/customer` and `/v2/customer` etc but I don't have experience to know how much of that is "in theory."

Re:Migrating to GraphQL: A Practical Assessment by pm90 on Sunday July 07, 2019 @12:19AM (#20373528)
Increasing the endpoints queried from 1 to greater than one would probably be a breaking change which is not allowed in graphql.