HTTP QUERY 方法是 IETF 正在推进的一项 HTTP 扩展草案(draft-ietf-httpbis-safe-method-w-body),旨在解决传统 GET 和 POST 在复杂查询场景下的痛点。它定义为一种安全(safe)和幂等(idempotent)的请求方法,能够携带请求体(body),特别适用于需要大负载参数的查询操作,同时支持缓存和自动重试。这种特性使其成为理想的无状态能力探测工具,尤其能避免 OPTIONS 方法的预检开销和有状态协商的复杂性。
传统能力发现依赖 OPTIONS 方法,例如客户端发送 OPTIONS /api/v1 HTTP/1.1 来查询服务器支持的 HTTP 方法列表,返回 Allow: GET, POST 等头。但 OPTIONS 存在局限:一是它通常不携带 body,无法表达复杂查询语义;二是 CORS 等场景下需预检请求,增加延迟;三是响应仅限于方法列表,无法细粒度描述如媒体类型或查询格式支持。相比之下,QUERY 方法桥接了 GET(无 body、幂等)和 POST(有 body、非幂等)的差距:请求体可承载 JSON 或自定义查询格式,服务器通过 Accept-Query 响应头声明支持的媒体类型,如 Accept-Query: application/json; q=0.9, application/x-www-form-urlencoded,实现服务器驱动的发现。
例如,在微服务架构中,客户端需探测后端支持的查询参数集,而非简单方法列表。使用 QUERY /capabilities HTTP/1.1 Content-Type: application/json {"formats": ["json", "xml"], "max-size": 1e6},服务器响应 200 OK Accept-Query: application/json,支持复杂能力描述,且整个过程幂等、无副作用。即使网络抖动,也可安全重试,而无需状态跟踪。
实施时,服务器端需优先配置 QUERY 处理逻辑。核心参数包括:
-
方法路由映射:在 Nginx 或 Envoy 等代理中添加 QUERY 支持,避免回退到 GET/POST。例如,Nginx 配置:
location /query {
if ($request_method = QUERY) {
proxy_pass http://backend;
proxy_set_header Accept-Query "application/json; q=1.0";
}
}
确保后端框架(如 Express.js)注册 QUERY handler:
app.QUERY('/capabilities', (req, res) => {
res.set('Accept-Query', 'application/json');
res.json({ supported: ['json', 'protobuf'], maxBody: '10MB' });
});
-
请求体解析与验证:QUERY body 推荐 JSON 或 form-urlencoded。设置 Content-Length 上限为 10MB,避免滥用。验证幂等性:不修改资源,仅读取/计算。使用规范化缓存键,如 Vary: Accept-Query, Content-Type,确保不同格式响应正确缓存。
-
响应头标准化:始终返回 Accept-Query 列出支持格式,按 q 值优先级排序。若不支持,返回 405 Method Not Allowed,并可选带 Allow 头列出备选。示例响应:
HTTP/1.1 200 OK
Accept-Query: application/json; q=1.0, text/csv; q=0.8
Cache-Control: public, max-age=3600
Content-Type: application/json
{"features": {"pagination": true, "sorting": ["asc", "desc"]}}
客户端调用清单,确保无状态探测:
-
初始探测:发送 QUERY /.well-known/capabilities,避免 OPTIONS 预检。Body: {"probe": ["methods", "formats"]}。
-
超时与重试:连接超时 5s,读取超时 30s。使用指数退避重试 3 次,间隙 100ms-1s,支持 HTTP/2 复用。
-
降级策略:若 405,则 fallback OPTIONS。若无 Accept-Query,假设不支持 body 查询,转 GET ?q=...。
-
监控指标:暴露 Prometheus 指标,如 query_probes_total{status=200|405},query_body_size_bytes,探测成功率 >99%。警报阈值:失败率 >1%,平均延迟 >100ms。
在分布式系统中,QUERY 还支持间接响应:服务器返回 303 See Other + Location: /query-results/123,客户端后续 GET 该 URI 获取结果,避免长连接。Content-Location 可锚定具体响应,便于缓存验证。
实际落地风险控制:一是浏览器支持有限,目前仅服务端实现;二是安全验证 body 防注入,使用 schema 校验如 JSON Schema。测试用 curl:curl -X QUERY -H "Content-Type: application/json" -d '{"test":1}' https://example.com/capabilities -v | jq .accept-query。
此方法已在 HN 社区热议,帖子“The HTTP Query Method”获 210 分、88 评论,反映行业需求。IETF 草案强调其对 API 设计的提升,尤其大数据查询场景。
资料来源:
通过以上参数,开发者可快速集成 QUERY,实现高效、无状态能力发现,推动 HTTP 生态演进。(字数:1268)