JSON-RPC 2.0规范 翻译 中文版

JSON-RPC 2.0规范

 

起源日期:

    2010-03-26(基于2009-05-24的版本)

修正:

    2013-01-04

作者:

    JSON-RPC 工作组 <[email protected]>

1 概述

JSON-RPC是一个无状态的、轻量级的远程过程调用(RPC)协议。本规范主要围绕它的处理方式定义了几个数据结构和规则。这个概念可用于在同一进程中、套接字或HTTP之间、或其他很多消息传递的环境中传输数据。它使用JSON (RFC 4627)作为数据格式。

JSON-RPC的设计很简单!

2 约定

本文档中的关键词“必须”、“必须不”、“要求”、“会”、“不会”、“应该”、“不应该”、“推荐”、“可能”和“可选的”与RFC 2119中翻译相同。

由于JSON-RPC使用JSON格式,它拥有与JSON相同的类型系统(见http://www.json.org 或 RFC 4627)。JSON可以表示4种原始类型(字符串、数值、布尔和Null)和两种结构化类型(对象和数组)。术语“原始类型”在本文档中代表这四种原始JSON类型中的任意一种。术语“结构化类型”代表结构化的JSON类型。本文档中的任意JSON类型,首字母总是大写:Object、Array、String、Number、Boolean、Null。True和False首字母同样是大写的。

客户端和服务器端交换的所有成员名字都是大小写敏感的。术语函数、方法和过程都认为是可交换的。

客户端被定义成原始请求对象和响应对象处理器。

服务器被定义成原始响应对象和请求对象处理器。

本规范的实现可以很容易的满足这些要求,即使对于其他不同的客户端或相同的客户端。本规范没有解决那一层次的复杂性。

3 兼容性

JSON-RPC 2.0请求对象和响应对象可能与已经存在的JSON-RPC1.0客户端或服务器端不兼容。然而,很容易区分两个版本,因为2.0版本总是包含一个名为“jsonrpc”的成员,其值为字符串“2.0”,而1.0版本不存在。大多数2.0版本的实现应该考虑处理1.0版本的对象,即使不是对等的,也应该给予良好的提示。

4 请求对象

发送一个请求对象到服务器表示一个RPC调用。请求对象包括下面这些成员:

jsonrpc

指定JSON-RPC版本的字符串,它必须是“2.0”。

method

调用的方法的名字。以rpc开头方法名表示rpc内部的方法和扩展,其他地方必须不能使用。

params

它是一个结构化的值,持有方法调用期间的参数值。该成员可省略。

id

客户端建立的一个标识符,如果请求中包含这个成员的话,它必须是字符串、数值或NULL值。如果没有包含该成员,那么它被认为是一个通知。这个值一般不应该为Null[1]并且如果是数值的话不应该包含小数部分[2]

如果客户端包含了id成员,那么服务器端必须包含同样的值在响应对象中。这个成员用于关联请求和响应这两个对象之间的上下文。

[1]不推荐在请求对象中使用Null作为id成员的值,因为本规范使用Null值作为对一个未知id的值。同样,由于JSON-RPC 1.0使用id值为Null来作为通知,在处理时这可能引起混淆。

[2]小数部分可能导致总是,因为很多小数不能被精确的表示成二进制形式。

4.1 通知

如果请求对象中没有“id”成员,则表示一个通知。通知请求对象表示客户端对相应的响应对象不感兴趣,因此不需要返回响应对象给客户端。服务器必须不回复一个通知,即使是在批量请求中。

由于不会返回响应对象,所以通知不容易定义。因此,客户端不会知道有任何错误(像:“无效的参数”、“内部错误”等)。

4.2 结构化参数

rpc调用如果存在参数,那么必须提供结构化的参数值。要么通过一个数组的位置,要么通过一个对象的名字。

通过位置:参数必须是一个数组,包含服务器期望的顺序的值。

通过名字:参数必须是一个对象,对象的成员名与服务器期望的参数名匹配。缺少期望的参数名可能导致错误。名字必须精确匹配,包括与方法期望的参数名的大小写。

5 响应对象

当发起rpc调用时,服务器必须回复一个响应,通知除外。响应被表示成一个单一的对象,包含下列的成员:

jsonrpc

指定JSON-RPC版本的字符串,它必须是“2.0”。

result

当调用成功时,该成员是必须的。

如果调用方法出现错误时,必须不包含该成员。

该成员的值由服务器上调用的方法决定。

error

当调用发生错误时,该成员是必须的。

在调用期间如果没有错误产生,必须不包含该成员。

该成员的值必须是一个5.1节定义的对象。

id

该成员是必须的。

它的值必须与请求对象中的id成员的值相同。

如果检查请求对象中的id时发生错误(如:转换错误或无效的请求),它必须为Null。

必须包含result或error成员,但是两个成员都必须不能同时包含。

5.1 错误对象

当一个rpc调用遇到错误时,响应对象必须包含一个值为对象的error成员,该对象包含下列的成员:

code

一个数字,表示发生错误的类型。

这个成员值必须是整型。

message

提供简短错误描述的字符串。

message应该限制为一个简短的句子。

data

原始类型或结构化类型值,包含了关于错误的附加信息。

这个成员可以省略。

该成员的值由服务器端定义(如:详细的错误信息,嵌套的错误信息等)。

错误代码值-32768到-32000为保留值,作为预定义错误。这个范围内的任何代码,但在下表中没有定义的值,保留作未来使用。这些错误代码几乎与下列地址中XML-RPC建议的相同( http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php)。

代码

消息

含义

-32700

解析错误

服务器接收到无效的JSON。

服务器解析JSON文本发生错误。

-32600

无效的请求

发送的JSON不是一个有效的请求。

-32601

方法未找到

方法不存在或不可见。

-32602

无效的参数

无效的方法参数。

-32603

内部错误

JSON-RPC内部错误。

-32000 to -32099

服务器端错误

保留给具体实现定义服务器端错误。

应用程序可以使用剩下的代码来定义错误。

6 批量调用

为了同时发送多个请求对象,客户端可以发送一个请求对象数组。

在所有批量请求对象都处理完成后,服务器应该使用一个数组作为响应,数组中包含相应的响应对象。每个请求对象都应该对应一个响应对象,像通知这样不应该有响应对象的除外。服务器可以以任何宽度的并行性,以任意的顺序,并发地处理一个批量rpc调用。

批量调用可以使用数组以任意的顺序返回响应对象。客户端可通过每个对象中包含的id成员在一系列请求对象和响应对象之间进行匹配。

如果批量rpc调用本身发生无效的JSON或一个至少包含一个值的数组导致失败,服务器生成的响应必须是一个单一的响应对象。如果发送到客户端的响应数组中不包含响应对象,那么服务器必须不能返回一个空的数组,而应该不返回任何东西。

7 示例

语法:

--> 表示数据发送到服务器端

<-- 表示数据发送到客户端

位置参数形式的rpc调用:

rpc call with positional parameters:

--> {"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"}

rpc调用一个不存在的方法:

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

无效的JSON的rpc调用

rpc call with invalid JSON:

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

rpc call with invalid Request object:

无效请求对象的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 call with an empty Array:

--> []

<-- {"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]}
    ]
<-- //批量通知调用什么也不返回

8 扩展

以rpc开关的方法名保留作系统扩展,其他任何地方都必须不能使用。每个系统扩展都定义在相关的规范中。所有系统扩展都是可选的。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。