fatihbm opened a new issue, #13807:
URL: https://github.com/apache/apisix/issues/13807

   ### 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](https://www.rfc-editor.org/rfc/rfc10008.html) 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:
   
   1. Existing client `POST` requests, forwarded unchanged. Caching is opt-in 
and available only when the route explicitly marks those POST requests as 
read-only.
   2. Client `QUERY` requests, forwarded as `POST` by default for compatibility 
with existing upstreams.
   3. Native QUERY upstreams, enabled per route or upstream when support 
becomes available.
   4. A local-memory cache by default, with optional Redis and Redis Cluster 
backends.
   5. A short, configurable local-memory fallback when a remote cache backend 
is unavailable.
   
   Example configuration:
   
   ```yaml
   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.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to