- 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.
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.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.
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.
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.
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.
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.
Also the tooling is next level . GraphIql alone is miles ahead of any REST tooling offerings. Also, typescript generation. Truly improved my workflow.
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.
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.
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."
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.