My post was only intended as a commentary regarding how I approach GraphQL after a few forays into it (current stance: would not default to GraphQL, but not against it either).
I was not intending to dodge your questions, but nor was I trying to comprehensively answer them, because they felt a bit unclear. I will make an attempt, combining snippets within your two posts that seem to be related:
>Shouldn't you always have some proper API abstraction between your components?
>But those endpoints are abstractions. Don't we want control over the surface of the API and our abstractions?
I can't answer this unless I know what concepts/layers you are referring to when you say "abstraction between components". If you mean "between the client and server", then yes, and GraphQL does this by way of the schema, types, and resolvers that the server supports, along with the query language itself. The execution is still occurring on the server, and the server still chooses what to implement and support.
If by "abstraction between components" you mean "URL endpoints and HTTP methods" then no, GraphQL chose to not have the abstraction be defined by the URL endpoint. If you use GraphQL, you do so having accepted that the decision point where resources are named is not at the URL or routing level. That doesn't make it not an abstraction, or not "proper" in some way.
>But the answer can't be have no APIs?
I don't understand what you mean by "No APIs"? You also mention "control over the surface"...
Is your concern that, because the client can ask the server "Please only respond with this subset of nodes, edges and properties: _______", the server has "no API"? Or it doesn't have "control"? I assure you that you can implement a server with whatever controls you desire. That doesn't mean it will always be easy, or be organized the way you are used to, or have the same performance profile you are used to, but the server can still implement whatever behavior it wants.
>...in general it seems you want to have a well controlled layer there the specifies the contract between these pieces.
I think this wording brings me closer to understanding your main concern.
First, let me repeat: I am not a big GraphQL fan, and am only explaining my understanding after implementing it on both clients and servers. I am not attempting to convince you this is good, only to explain a GraphQL approach to these matters.
The "well-controlled layer" is the edge between nodes, implemented as resolvers. This was the "aha" moment for me in implementing GraphQL the first time: edges are a first-class concept, not just the nodes/entities. If you try using GraphQL in a small project whose domain model has lots of "ifs" and "buts", you will be forced to reach for that layer of control, and get a sense of it. It is simply located in a different place than you are used to.
This "edges are first-class concepts" has an analogue in proper hypermedia REST APIs, but most organizations don't implement REST that way, so except for the five people who fully implement true HATEOAS, it is mostly beside the point.