新的 HTTP QUERY 方法解析

QUERY 旨在解决什么问题

  • 被视为“带有请求体的 GET”的正式化版本:安全、幂等、可缓存,但可以携带请求体。
  • 旨在取代诸如 GET-with-body 或用于查询的 POST 之类的变通做法(例如搜索、GraphQL 查询)。
  • 支持者认为这能让中间件语义更清晰:“它可以被缓存、只读,而且带有请求体。”

为什么不直接修复 GET?

  • 一种观点:只需把 GET-with-body 标准化即可;QUERY 是多余的 “XKCD 标准” 膨胀。
  • 反方观点:许多现有代理、WAF、CDN 和框架会删除或拒绝 GET 请求体,或者把它们当成无意义的东西。
  • 改变 GET 语义会在遗留系统中产生未定义行为;新增方法可以干净地以 405 失败,并允许回退到 POST。
  • 也有人认为两条路径都需要更新基础设施;他们把 QUERY 看作营销而非技术必要性。

兼容性、中间盒与浏览器

  • 有人担心维护不佳的“黑盒”中间件可能会错误处理新动词,甚至崩溃。
  • 也有人认为标准必须随着时代演进;过时设备应该修复。
  • 多位评论者指出,浏览器不太可能(至少短期内不保证)很快实现 QUERY;这限制了面向 Web 的采用。
  • Accept-Query 头以及 OPTIONS/405 被提及为协商支持的机制。

拟议用例

  • 像 Elastic/OpenSearch 这样的搜索 API 目前在滥用 GET-with-body 或 POST;QUERY 会是很自然的选择。
  • GraphQL:用 QUERY 表示只读查询,用 POST 表示 mutation。
  • Web 应用中的复杂过滤/搜索:用 JSON 请求体代替过长的查询字符串。
  • 反向图片搜索以及其他基于文件或二进制的查询。

缓存、语义与 REST

  • QUERY 被定义为可缓存且幂等;这使其能够像 POST 不能做到的那样利用 CDN/代理缓存。
  • 怀疑者指出现实中的缓存键问题:请求体没有标准化的规范形式(JSON 顺序、空白字符),这会让共享缓存变得复杂。
  • 有人认为 QUERY 通过将简单的基于 URL 的 GET 与更复杂的查询分离开来,提升了 REST/CRUD 的清晰度;也有人认为你可以把查询建模为资源(用 POST 创建,然后用 GET 获取)。

安全、WAF 与实际痛点

  • 很多人指出现实系统会拒绝或删除 GET 请求体(WAF、CloudFront、严格的 API 网关)。
  • QUERY 被视为一种避免这些未定义行为以及将 GET-with-body 视为可疑的安全规则的方法。
  • 也有人警告,QUERY 本身一开始也不会被这类系统支持,所以迁移仍然不简单。