JSON-RPC 2.0 规范

以下内容为deepseek-v4翻译

JSON-RPC 2.0 规范

  • 原始日期:2010年3月26日(基于2009年5月24日版本)
  • 更新日期:2013年1月4日
  • 作者:JSON-RPC 工作组

1 概述

JSON-RPC 是一种无状态、轻量级的远程过程调用(RPC)协议。本规范主要定义了一些数据结构及其处理规则。它与传输无关,可以在同一进程内、通过套接字、通过 HTTP 或各种消息传递环境中使用。它使用 JSONRFC 4627)作为数据格式。

它被设计为简单易用!

2 约定

本文档中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL” 应按照 RFC 2119 的描述进行解释。

由于 JSON-RPC 使用 JSON,因此它具有相同的类型系统(参见 http://www.json.orgRFC 4627)。JSON 可以表示四种基本类型(字符串、数字、布尔值和 Null)和两种结构化类型(对象和数组)。本规范中的术语”基本类型”指代这四种基本 JSON 类型中的任何一种。术语”结构化类型”指代这两种结构化 JSON 类型中的任何一种。每当本文档提及任何 JSON 类型时,首字母始终大写:Object、Array、String、Number、Boolean、Null。True 和 False 也大写。

客户端与服务器之间交换的所有成员名称,在进行任何类型的匹配时,都应视为区分大小写。

术语 function、method 和 procedure 可以假定为可互换的。

客户端被定义为 Request 对象的发起者和 Response 对象的处理者。服务器被定义为 Response 对象的发起者和 Request 对象的处理者。本规范的一种实现可以轻松地同时扮演这两个角色,甚至可以对其他不同的客户端或同一客户端同时扮演这两个角色。本规范不涉及这种复杂性层面。

3 兼容性

JSON-RPC 2.0 的 Request 对象和 Response 对象可能无法与现有的 JSON-RPC 1.0 客户端或服务器兼容。但是,很容易区分这两个版本,因为 2.0 始终有一个名为 “jsonrpc” 的成员,其 String 值为 “2.0”,而 1.0 没有。大多数 2.0 实现应该考虑尝试处理 1.0 对象,即使不处理 1.0 的点对点和类提示方面。

4 Request 对象

一个 rpc 调用通过向服务器发送一个 Request 对象来表示。Request 对象具有以下成员:

  • jsonrpc - 一个 String,指定 JSON-RPC 协议的版本。必须(MUST)精确为 “2.0”。
  • method - 一个 String,包含要调用的方法的名称。以单词 rpc 后跟句点字符(U+002E 或 ASCII 46)开头的方法名称保留用于 rpc 内部方法和扩展,并且不得(MUST NOT)用于任何其他用途。
  • params - 一个 Structured 值,保存在调用方法期间要使用的参数值。此成员可以(MAY)省略。
  • id - 由客户端建立的标识符,如果包含,则必须(MUST)包含一个 String、Number 或 NULL 值。如果不包含,则假定为通知。该值通常不应(SHOULD NOT)为 Null [1],并且 Numbers 不应(SHOULD NOT)包含小数部分 [2]。如果包含,服务器必须(MUST)在 Response 对象中以相同的值回复。此成员用于关联两个对象之间的上下文。

[1] 不鼓励在 Request 对象中使用 Null 作为 id 成员的值,因为本规范对未知 id 的 Responses 使用 Null 值。此外,由于 JSON-RPC 1.0 对 Notifications 使用 Null 的 id 值,这可能会导致处理上的混淆。

[2] 小数部分可能会产生问题,因为许多十进制小数无法精确表示为二进制小数。

4.1 通知

通知是没有 “id” 成员的 Request 对象。作为通知的 Request 对象表示客户端对相应的 Response 对象不感兴趣,因此不需要向客户端返回 Response 对象。服务器不得(MUST NOT)回复通知,包括批处理请求中的通知。

通知在定义上是不可确认的,因为它们没有要返回的 Response 对象。因此,客户端不会意识到任何错误(例如 “Invalid params”、“Internal error”)。

4.2 参数结构

如果存在,rpc 调用的参数必须(MUST)作为结构化值提供。可以通过数组按位置传递,或通过对象按名称传递。

  • 按位置传递:params 必须(MUST)是一个数组,包含服务器预期顺序的值。
  • 按名称传递:params 必须(MUST)是一个对象,其成员名称与服务器预期的参数名称匹配。缺少预期名称可能导致(MAY)生成错误。名称必须(MUST)精确匹配,包括大小写,与方法的预期参数一致。

5 Response 对象

当进行 rpc 调用时,除非是通知,否则服务器必须(MUST)回复一个 Response。Response 表示为一个单一的 JSON Object,具有以下成员:

  • jsonrpc - 一个 String,指定 JSON-RPC 协议的版本。必须(MUST)精确为 “2.0”。
  • result - 此成员在成功时是必需的(REQUIRED)。如果在调用方法时发生错误,则此成员不得(MUST NOT)存在。此成员的值由服务器上调用的方法确定。
  • error - 此成员在出错时是必需的(REQUIRED)。如果在调用期间未触发错误,则此成员不得(MUST NOT)存在。此成员的值必须(MUST)是如 5.1 节中定义的对象。
  • id - 此成员是必需的(REQUIRED)。它必须(MUST)与 Request 对象中 id 成员的值相同。如果在检测 Request 对象中的 id 时发生错误(例如 Parse error/Invalid Request),则必须(MUST)为 Null。

必须(MUST)包含 result 成员或 error 成员,但不得(MUST NOT)同时包含两者。

5.1 Error 对象

当 rpc 调用遇到错误时,Response 对象必须(MUST)包含 error 成员,其值是一个具有以下成员的对象:

  • code - 一个 Number,指示发生的错误类型。这必须(MUST)是一个整数。
  • message - 一个 String,提供错误的简短描述。消息应该(SHOULD)限制为一句话,简洁明了。
  • data - 一个基本类型或结构化类型值,包含有关错误的附加信息。这可以省略。此成员的值由服务器定义(例如,详细的错误信息、嵌套错误等)。

从 -32768 到 -32000 的错误代码(包括两端)保留用于预定义错误。此范围内但未在下面明确定义的任何代码保留供将来使用。错误代码与以下网址为 XML-RPC 建议的代码几乎相同:http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php

codemessagemeaning
-32700Parse error服务器接收到无效的 JSON。服务器在解析 JSON 文本时发生错误。
-32600Invalid Request发送的 JSON 不是有效的 Request 对象。
-32601Method not found方法不存在/不可用。
-32602Invalid params无效的方法参数。
-32603Internal error内部 JSON-RPC 错误。
-32000 to -32099Server error保留用于实现定义的服务器错误。

其余空间可用于应用程序定义的错误。

6 批处理

要同时发送多个 Request 对象,客户端可以(MAY)发送一个填充了 Request 对象的数组。

服务器在所有批处理 Request 对象处理完毕后,应该(SHOULD)以包含相应 Response 对象的数组进行响应。每个 Request 对象应该(SHOULD)存在一个 Response 对象,但通知不应(SHOULD NOT)有任何 Response 对象。

服务器可以(MAY)将批处理 rpc 调用作为一组并发任务处理,以任何顺序和任何并行宽度处理它们。从批处理调用返回的 Response 对象可以(MAY)以任何顺序在数组中返回。客户端应该(SHOULD)根据每个对象中的 id 成员,在 Request 对象集和结果 Response 对象集之间匹配上下文。

如果批处理 rpc 调用本身无法识别为有效的 JSON 或至少包含一个值的数组,则服务器的响应必须(MUST)是单个 Response 对象。如果要发送给客户端的 Response 数组中没有 Response 对象,则服务器不得(MUST NOT)返回空数组,而应该什么都不返回。

7 示例

语法:

  • --> 发送到服务器的数据
  • <-- 发送到客户端的数据

带位置参数的 rpc 调用:

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}

--> {"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}
<-- {"jsonrpc": "2.0", "result": -19, "id": 2}

带命名参数的 rpc 调用:

--> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
<-- {"jsonrpc": "2.0", "result": 19, "id": 3}

--> {"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}
<-- {"jsonrpc": "2.0", "result": 19, "id": 4}

通知:

--> {"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}
--> {"jsonrpc": "2.0", "method": "foobar"}

调用不存在的方法:

--> {"jsonrpc": "2.0", "method": "foobar", "id": "1"}
<-- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}

无效 JSON 的 rpc 调用:

--> {"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]
<-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}

无效 Request 对象的 rpc 调用:

--> {"jsonrpc": "2.0", "method": 1, "params": "bar"}
<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}

无效 JSON 的 rpc 批处理调用:

--> [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}, {"jsonrpc": "2.0", "method" ]
<-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}

空数组的 rpc 调用:

--> []
<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}

无效(但非空)批处理的 rpc 调用:

--> [1]
<-- [ {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null} ]

无效批处理的 rpc 调用:

--> [1,2,3]
<-- [ {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null} ]

rpc 批处理调用:

--> [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}, {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}, {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"}, {"foo": "boo"}, {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"}, {"jsonrpc": "2.0", "method": "get_data", "id": "9"} ]
<-- [ {"jsonrpc": "2.0", "result": 7, "id": "1"}, {"jsonrpc": "2.0", "result": 19, "id": "2"}, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}, {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"}, {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"} ]

rpc 批处理调用(全部为通知):

--> [ {"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]}, {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]} ]
<-- //Nothing is returned for all notification batches

8 扩展

rpc. 开头的方法名称保留用于系统扩展,并且不得(MUST NOT)用于任何其他用途。每个系统扩展都在相关的规范中定义。所有系统扩展都是可选的(OPTIONAL)。


版权 (C) 2007-2010 由 JSON-RPC 工作组所有。

本文档及其翻译可用于实现 JSON-RPC,可以复制并提供给他人,并且可以制作、复制、出版和分发对其进行评论、解释或协助其实施的衍生作品,全部或部分,不受任何限制,前提是上述版权声明和本段包含在所有此类副本和衍生作品中。但是,本文档本身不得以任何方式进行修改。

上述授予的有限许可是永久性的,不会撤销。

本文档及其中包含的信息按”原样”提供,并且所有明示或暗示的保证均予免责,包括但不限于对使用本文中的信息不会侵犯任何权利的任何保证,或对适销性或特定用途适用性的任何暗示保证。