Description
Background
Many search, analytics, reporting, and query APIs accept a request body but are logically read-only. Today, clients and upstreams commonly use POST for those requests. While compatible, POST alone does not communicate that the operation is safe and idempotent, and it makes result caching an application-specific and potentially unsafe decision.
RFC 10008 defines the HTTP QUERY method for safe, idempotent requests that carry request content. It also permits caching QUERY responses, with a cache key that incorporates request content and relevant metadata.
The main need is therefore not only QUERY-to-POST compatibility. APISIX should provide a safe cache boundary for explicitly read-only, body-carrying queries even when both the client and the upstream use POST today. QUERY support is an optional compatibility and migration capability on top of that.
Proposal
Add a query-gateway plugin for safe, cache-aware handling of read-only HTTP queries with request bodies.
The plugin would support:
- Existing client
POST requests, forwarded unchanged. Caching is opt-in and available only when the route explicitly marks those POST requests as read-only.
- Client
QUERY requests, forwarded as POST by default for compatibility with existing upstreams.
- Native QUERY upstreams, enabled per route or upstream when support becomes available.
- A local-memory cache by default, with optional Redis and Redis Cluster backends.
- A short, configurable local-memory fallback when a remote cache backend is unavailable.
Example configuration:
plugins:
query-gateway:
preserve_original_method_header: true
original_method_header: X-Original-Method
query:
# Default: client QUERY -> upstream POST
upstream_method: post
# For a native QUERY upstream:
# upstream_method: query
post:
# Existing POST requests remain POST.
# Cache is enabled only when both options are explicit.
cache_enabled: true
read_only: true
cache:
enabled: true
backend: local
ttl: 30
fallback_ttl: 5
Cache safety model
Caching must be conservative. The cache key should include the route, target URI, client method, request content and content type, relevant content-negotiation metadata, approved cookie values, and applicable identity context.
The plugin should bypass cache for requests that include:
Authorization or Range;
Cache-Control: no-store or no-cache;
Pragma: no-cache;
- cookies outside an explicit allow-list;
- a missing
Content-Type;
- request or response bodies beyond configured limits.
It should not store responses that include:
Set-Cookie, WWW-Authenticate, Proxy-Authenticate, or Content-Range;
Cache-Control: private, no-store, no-cache, max-age=0, or s-maxage=0;
Vary values outside a conservative allow-list.
Use cases
- Elasticsearch and OpenSearch search endpoints;
- ClickHouse analytical queries;
- reporting, filtering, and dashboard APIs;
- GraphQL or JSON-based read-only query APIs;
- gradual migration from POST-based queries to RFC 10008 QUERY without changing the external API contract;
- sharing query results across APISIX instances with Redis or Redis Cluster.
Proposed validation
The feature should include unit tests and a separate integration profile that builds APISIX from source and exercises a real Elasticsearch upstream. The profile should verify:
- QUERY and explicitly read-only POST cache
MISS -> HIT flows;
- cache bypass for credential-bearing requests;
- negative
Content-Type cases;
- that cache hits do not reach the upstream;
- correlation of client, APISIX, and upstream logs with
X-Opaque-ID.
Scope and non-goals
This proposal does not attempt to:
- add native QUERY support to every upstream or to the Nginx/OpenResty core;
- cache arbitrary POST traffic or write operations;
- cache user-specific or session-bound responses by default;
- define a global distributed-cache invalidation protocol.
Feedback is especially welcome on the cache-safety rules, the read-only POST opt-in model, and Redis/Redis Cluster fallback behavior.
Description
Background
Many search, analytics, reporting, and query APIs accept a request body but are logically read-only. Today, clients and upstreams commonly use
POSTfor those requests. While compatible,POSTalone does not communicate that the operation is safe and idempotent, and it makes result caching an application-specific and potentially unsafe decision.RFC 10008 defines the HTTP
QUERYmethod for safe, idempotent requests that carry request content. It also permits caching QUERY responses, with a cache key that incorporates request content and relevant metadata.The main need is therefore not only QUERY-to-POST compatibility. APISIX should provide a safe cache boundary for explicitly read-only, body-carrying queries even when both the client and the upstream use
POSTtoday. QUERY support is an optional compatibility and migration capability on top of that.Proposal
Add a
query-gatewayplugin for safe, cache-aware handling of read-only HTTP queries with request bodies.The plugin would support:
POSTrequests, forwarded unchanged. Caching is opt-in and available only when the route explicitly marks those POST requests as read-only.QUERYrequests, forwarded asPOSTby default for compatibility with existing upstreams.Example configuration:
Cache safety model
Caching must be conservative. The cache key should include the route, target URI, client method, request content and content type, relevant content-negotiation metadata, approved cookie values, and applicable identity context.
The plugin should bypass cache for requests that include:
AuthorizationorRange;Cache-Control: no-storeorno-cache;Pragma: no-cache;Content-Type;It should not store responses that include:
Set-Cookie,WWW-Authenticate,Proxy-Authenticate, orContent-Range;Cache-Control: private,no-store,no-cache,max-age=0, ors-maxage=0;Varyvalues outside a conservative allow-list.Use cases
Proposed validation
The feature should include unit tests and a separate integration profile that builds APISIX from source and exercises a real Elasticsearch upstream. The profile should verify:
MISS -> HITflows;Content-Typecases;X-Opaque-ID.Scope and non-goals
This proposal does not attempt to:
Feedback is especially welcome on the cache-safety rules, the read-only POST opt-in model, and Redis/Redis Cluster fallback behavior.