* It's fairly easy to tell "how the app is using the database" -- queries are not dynamically generated or hidden in code.
* The query performance is predictable and controllable in the same way as a stored procedure approach to database access -- but without actually requiring a DBA to load/unload procedure definitions.
One might argue that these benefits could be obtained without codifying a new query language...but when you start to think about nested objects you start to warm up to the idea.
You do, but any time you try to solve a problem, and your solution ends up being a new language, I think it's worth asking yourself, "Am I overcomplicating this? Can I do this in a simpler way?"
And I think you can. I've been toying with an approach I like to call http-etc, which is a simple idea that lets you flag the http (rest) api to say, "Give me this data, but also give me the graph associated with this data."
For instance, if I want an article, I would do:
But if I want an article, plus the comments associated with it, and information about the users that posted those comments, I can do:
And this is handled completely with your server-side api design. You have your singular route to one function, and you have your "etc" route to another function. Synchronizing the shape of the data requested/returned between server and client is still handled manually, but it seems to me this pattern solves 90% of GraphQL use cases with 1% of the complexity of GraphQL. It isn't tied to any specific language or codebase on the server-side. It doesn't require a big client-side library be added to your project. It's just a simple pattern.