发布 GraphQL over HTTP 规范
自 2015 年 GraphQL 首次发布以来,GraphQL 规范一直与传输方式无关。
GraphQL 规范的大部分内容都围绕“服务”展开:接收“请求”、执行请求并生成“响应”。这些请求和响应如何发送和接收,由实现者决定。
这通常很有用。你可以在本地机器上、通过原始 TCP、信鸽或其他任何方式使用 GraphQL。不过,对于大量通过 HTTP 使用 GraphQL 的人来说,缺乏规范使得与其他 HTTP 工具的互操作性以及可观测性变得比应有的更困难。
随着 GraphQL over HTTP 规范首个版本的发布,今天这种情况正在改变!
GraphQL 规范仍保持传输无关;GraphQL over HTTP 规范是一份新文档,是对主 GraphQL 规范的补充。
如果你通过 HTTP 使用 GraphQL,请遵循规范中的指导,并确保你的服务器、客户端、代理和其他服务能够良好协同工作。
更好的可观测性
GraphQL over HTTP 规范包含新的 application/graphql-response+json 媒体类型。
此前,许多 GraphQL 服务器使用 application/json 作为响应。这使得客户端很难区分来自源服务器的格式正确的 GraphQL 响应,与来自代理、缓存或其他网络中间件的错误响应。
作为一种变通方法,大多数实现将状态码设置为 200:如果客户端收到 200 状态码,它就知道响应没有被篡改,可以安全地将其解析为 GraphQL 响应。
从可观测性的角度看,这并不理想,还引出了关于“200 Not OK”的玩笑。如果一切都是 200,就很难获取服务的状态……
现在这已得到修复!
当客户端收到 application/graphql-response+json 响应体时,它知道无论状态码是什么,都可以将其解析为格式正确的 GraphQL over HTTP 响应。
通用规则是:
- 如果请求返回了数据,则返回 2xx 状态码。
- 如果请求仅返回错误,则返回 4xx 或 5xx 状态码。
规范包含了关于应使用哪些状态码的详细指导,但如果替代状态码更适合具体情况,实现者也可以选择使用它,只要它与通用规则一致。常见状态码包括:
- 通过 GET 尝试执行 mutation 时返回 405
- 请求不支持的媒体类型时返回 406
- 提供不支持的媒体类型时返回 415
- 请求头过大时返回 431
- 发生服务器错误时返回 500
成功响应如下所示:
HTTP/1.1 200 OK
Content-Type: application/graphql-response+json
...
{
"data": {
"hello": "world"
}
}
请求错误如下所示:
HTTP/1.1 422 Unprocessable Content
Content-Type: application/graphql-response+json
...
{
"errors": [{
"message": "Cannot query field 'foo' on type 'Query'."
}]
}
规范还引入了新的 294 Partial Success 状态码,用于同时存在 data 和 errors 的情况;你可以在非规范性说明中了解更多关于 294 Partial Success 的内容。
记录基础内容
撇开“200 Not OK”问题不谈,过去十年里,GraphQL over HTTP 的许多方面一直运行得非常好。
本规范记录了所有这些内容:
- GET 请求
- POST 请求
- JSON 编码
它还包含关于安全性、部分成功和未来兼容性的非规范性说明。
接下来是什么?
这只是开始!
IETF 刚刚将 QUERY HTTP 动词推进为拟议标准。
QUERY 非常适合 GraphQL,我们已经有计划支持它。我们不想推迟这个初始版本,也不想仓促实现,但我们希望将它纳入 GraphQL over HTTP 规范的下一个修订版。
另一项将从标准化中受益的是 Persisted documents。持久化 GraphQL 文档(“persisted queries”)的技术早在 2015 年 GraphQL 开源之前就已在使用,不同的实现解决不同的问题:性能、安全、可观测性。我们渴望与社区合作,构建一种标准方法,既能解决所有这些问题,又能保留未来的可扩展性。
最后,请求批处理将是一个巨大的胜利,特别是在复合 schema(Federation)的上下文中,或者在向你不控制的 schema 发起请求时。
立即采用!
如果你是 GraphQL 用户,很可能你已经在不知不觉中使用了新规范!大多数现有的 GraphQL 框架和库已经支持新规范。
如果你是库作者,不妨试试新规范!
无论如何,请告诉我们你的想法!