Persisted Query
Registering allowed queries in advance and having clients send an identifier instead of the query text.
Solves several GraphQL problems at once, which is why it is standard practice for public GraphQL APIs.
Security: because the client controls query shape, a deeply nested or expensive query is a denial-of-service vector. If only registered queries may run, arbitrary queries are impossible — which is a stronger control than depth limiting or complexity scoring, though those remain useful.
Performance: the payload becomes a short hash rather than a query document, and the server can pre-parse and pre-plan.
Caching: a stable identifier can be sent as a GET, restoring HTTP caching and CDN behaviour, which ordinary GraphQL over POST loses.
The trade is deployment coupling: a new query must be registered before the client using it ships. Automatic persisted queries soften this by allowing an unregistered query once, then caching it — at the cost of the security benefit unless the registry is closed.