advanced 2 min answer

A team is about to launch a public GraphQL API. What must be in place before it goes live?

graphqlsecurityperformancecaching
Show the full answer Hide the answer

Query cost control — the security requirement

An arbitrary query language exposed publicly means a client can construct a query that consumes unbounded resources: deep nesting, recursive relationships, or wide fan-out through list fields.

Persisted queries are the strongest control. Only registered queries may run, so an expensive unregistered query is impossible. They also shrink the payload to a hash, allow pre-parsing and pre-planning, and — because a stable identifier can be sent as a GET — restore HTTP and CDN caching that GraphQL-over-POST loses.

The cost is deployment coupling: a query must be registered before the client using it ships. Automatic persisted queries soften this but forfeit the security benefit unless the registry is closed.

If persisted queries are not viable, you need depth limiting, complexity scoring with a per-caller budget, and pagination limits on every list field — weaker, and each requires tuning.

N+1 elimination — the performance requirement

DataLoader-style batching with per-request caching is a prerequisite, not an optimisation. Field resolvers run per item, so 100 orders each resolving a customer is 101 queries. Without batching the service will not survive production traffic.

It belongs in the service template so no resolver is written without it.

Authorisation at the field level

REST authorises per endpoint. GraphQL composes arbitrarily, so authorisation must be enforced in resolvers, on the field. A single unchecked resolver is reachable through any query that can traverse to it — and the traversal path may be one nobody anticipated.

Observability that reflects the model

Per-endpoint metrics are meaningless when there is one endpoint. Instrument per operation name and per resolver: which operations are slow, which resolvers dominate, which fields are actually used.

Field usage data is also what makes deprecation possible later.

Errors and rate limiting

GraphQL returns 200 with an errors array, including partial success. Clients and monitoring must handle partial failure explicitly, and an alert on HTTP status alone will see nothing wrong.

Rate limiting by request count is meaningless when one request can be 1,000× another. Limit by computed query cost.

What a strong answer adds

Asking whether GraphQL is warranted. Its benefit is greatest with many heterogeneous clients. For a single client, or a partner API where consumers expect REST, the operational cost — caching complexity, cost analysis, field-level authorisation, bespoke observability — usually outweighs the flexibility.