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開關的方法名保留作系統擴展,其他任何地方都必須不能使用。每個系統擴展都定義在相關的規範中。所有系統擴展都是可選的。