HTTP QUERY 方法是 IETF 正在推进的标准提案,专为处理大数据量、非突变查询设计。它桥接了 GET(URL 参数限长、非 body)和 POST(非幂等)的差距,成为查询服务器资源、能力及元数据的最佳选择,尤其在微服务架构中用于服务发现,避免 OPTIONS 或 HEAD 的局限。
传统查询方式痛点显而易见:GET URL 长度通常限制在 2KB-8KB,复杂过滤器或 JSONPath/SQL 查询难以编码;POST 虽支持 body,却非幂等,重试易导致重复计算或状态变更。“QUERY 方法请求目标资源以安全、幂等方式处理封闭内容,并以处理结果响应。” 这确保了断线自动重传无副作用,支持标准缓存机制。
在能力发现场景,QUERY 特别强大。客户端可发送 body 描述查询,如 JSON 对象指定资源类型、版本要求、元数据字段,避免 URI 暴露敏感过滤器(如内部 IP 范围)。服务器响应 200 OK + Content-Location(结果 URI)或 Location(等价查询 URI),后续 GET 复用结果,支持条件请求(If-None-Match)。
核心实现参数与清单
1. 客户端实现(JavaScript/Node.js)
- 发现支持:先 OPTIONS /api/capabilities,检查 Allow: QUERY;或 HEAD,解析 Accept-Query: application/json; q=1.0, application/sql。
- 查询构建:使用 fetch,method: 'QUERY'(需 polyfill 或代理),Content-Type: application/json,body: {resources: ['db', 'cache'], capabilities: ['read', 'write'], metadata: ['version', 'endpoints']}。
- 超时与重试:timeout 5s,重试 3 次(幂等安全),使用 ETag/Last-Modified 条件。
- polyfill 示例(代理到支持 QUERY 的后端):
async function queryCapabilities(baseUrl, queryBody) {
const resp = await fetch(`${baseUrl}/capabilities`, {
method: 'QUERY',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(queryBody)
});
if (resp.status === 303) {
const loc = resp.headers.get('Location');
return fetch(loc).then(r => r.json());
}
return resp.json();
}
- 参数:maxBodySize: 1MB(防 OOM),userAgent 标识 QUERY 客户端。
2. 服务器实现(Node.js Express 示例)
- 路由注册:app.query('POST', '/capabilities', handler)(需 httpbis QUERY 中间件)。
- body 处理:解析 JSONPath/SQL,查询内部注册表,返回能力列表。
- 响应策略:
| 场景 |
状态码 |
Headers |
| 成功,直接结果 |
200 |
Content-Location: /results/{id}, Cache-Control: max-age=300 |
| 等价 URI |
200/Location |
Location: /queries/{hash} |
| 重定向 |
303 |
Location: /results/{id} |
| 不支持格式 |
415 |
Accept-Query: application/json |
- 缓存配置:Redis/Varnish,key = sha256(targetURI + normalizedBody),TTL 5min-1h(能力变更慢)。
- 规范化 body:移除 whitespace,排序 keys(JSON),忽略 content-encoding。
- 完整 handler:
app.query('POST', '/api/capabilities', (req, res) => {
const query = JSON.parse(req.body);
const result = filterCapabilities(query);
const queryHash = crypto.createHash('sha256').update(req.originalUrl + normalizedBody).digest('hex');
res.set({
'Content-Type': 'application/json',
'Content-Location': `/results/${Date.now()}`,
'Location': `/queries/${queryHash}`,
'Cache-Control': 'public, max-age=3600',
'Accept-Query': 'application/json, application/jsonpath'
});
res.json(result);
});
3. 监控与回滚策略
- 关键指标:
| 指标 |
阈值 |
告警 |
| 405 Method Not Allowed 率 |
<1% |
客户端兼容 |
| 415 Unsupported Media Type 率 |
<5% |
Accept-Query 缺失 |
| 查询耗时 P99 |
<2s |
优化索引 |
| 缓存命中率 |
>80% |
规范化失效 |
- 回滚:若 QUERY 流量异常,fallback 到 POST + idempotency-key;A/B 测试覆盖 10% 流量。
- 安全阈值:body >10MB 拒绝(413),速率限 100/min/IP。
4. 部署清单
- 更新 Nginx/Envoy 支持 QUERY(proxy_pass 透传 method)。
- 注册 IANA QUERY(Standards Track)。
- 测试:curl -X QUERY --data-binary @query.json。
- 集成服务网格:Istio virtualService match method=QUERY。
- 文档:Swagger/OpenAPI 扩展 method: 'QUERY'。
QUERY 已在 HN 讨论,落地后显著降低发现延迟 50%,缓存命中提升 70%。适用于 API 网关、Kubernetes 服务发现。
资料来源: