Date: | 2009-05-24 |
---|---|
Author: | JSON-RPC Working Group <json-rpc(at)googlegroups.com> |
Table of Contents
JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. It uses JSON (RFC 4627) as data format, and is transport-independent. It's designed to be simple!
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Since JSON-RPC uses JSON, it shares the same type system as JSON (see http://www.json.org or RFC 4627). Whenever this document refers to any JSON type, the first letter is always capitalized: Object, Array, String, Number, True, False, Null.
All names (i.e. method-names or parameter-names) are case-sensitive.
Clients are the origin of Request objects. Servers are the origin of Response objects.
JSON-RPC 2.0 does not work with JSON-RPC 1.0 clients or servers.
But it's easy to distinguish between JSON-RPC 2.0 and JSON-RPC 1.0 (due to the "jsonrpc"-version-field), and e.g. to create a combined JSON-RPC 1.0/2.0-server.
A remote procedure call is made by sending a Request to a remote service. The Request is expressed as a single JSON Object, with the following members:
A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".
If jsonrpc is missing, the server MAY handle the Request as JSON-RPC V1.0-Request.
A String containing the name of the procedure to be invoked.
Procedure names that begin with the word rpc followed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and MUST NOT be used for anything else.
This id can be used to correlate a Response with its Request. The server MUST reply with the same value.
Every Request, except Notifications, MUST be replied to with a Response.
[1] | The use of Null for id in Requests is discouraged, because this specification uses an id of Null for Responses with an unknown id, and because JSON-RPC 1.0 uses an id of Null for Notifications. |
[2] | Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. |
A Notification is a special Request, without id and without Response. The server MUST NOT reply to a Notification.
Note that Notifications are unreliable by definition, since they do not have a Response, and so you cannot detect errors (like e.g. "Invalid params.", "Internal error.", timeouts or maybe even lost packets on the wire).
Parameters for a procedure call can be specified by-position, or by-name.
The position and name of a parameter is defined by the formal argument list of the procedure.
Mixing positional and named parameters in one call is not possible.
When a remote procedure call is made, the service MUST reply with a Response (except for Notifications). The Response is expressed as a single JSON Object, with the following members:
Exactly one of result or error MUST be specified. It's not allowed to specify both or none.
When a remote procedure call fails, the Procedure Return object MUST contain the error member whose value is a JSON Object with the following members:
The error-codes -32768 .. -32000 (inclusive) are reserved for pre-defined errors. Any error-code within this range not defined explicitly below is reserved for future use. [3]
code | message | Meaning |
---|---|---|
-32700 | Parse error. | Invalid JSON. An error occurred on the server while parsing the JSON text. |
-32600 | Invalid Request. | The received JSON is not a valid JSON-RPC Request. |
-32601 | Method not found. | The requested remote-procedure does not exist / is not available. |
-32602 | Invalid params. | Invalid method parameters. |
-32603 | Internal error. | Internal JSON-RPC error. |
-32099..-32000 | Server error. | Reserved for implementation-defined server-errors. |
The remainder of the space is available for application defined errors.
[3] | The error-codes are nearly the same as specified for XML-RPC at http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php |
It's also possible to batch several procedure-calls, by sending an Array of Requests to a remote service.
The response is an Array of Responses, in the same order as the Requests (except for Notifications, which don't have a response).
If the multicall itself fails, the reply is a single error-Response.
Note that the Requests may be processed in parallel, so don't rely on a specific processing-order of the Requests.
Syntax:
--> data sent to service <-- data coming from service
Procedure 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}
Procedure Call with named parameters:
--> {"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}
Notification:
--> {"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]} --> {"jsonrpc": "2.0", "method": "foobar"}
Procedure Call of non-existent procedure:
--> {"jsonrpc": "2.0", "method": "foobar", "id": "1"} <-- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Procedure not found."}, "id": "1"}
Procedure Call with invalid JSON:
--> {"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz] <-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error."}, "id": null}
Procedure Call with invalid JSON-RPC:
--> [1,2,3] <-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null} --> {"jsonrpc": "2.0", "method": 1, "params": "bar"} <-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null}
Batched Call:
--> [ {"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"} ]
Batched Call itself fails:
--> [ {"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}
Procedure names that begin with rpc. are reserved for system extensions, and MUST NOT be used for anything else. Each system extension is defined in a related specification. All system extensions are OPTIONAL.
Copyright (C) 2007-2009 by JSON-RPC Working Group
This document and translations of it may be used to implement JSON-RPC, it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way.
The limited permissions granted above are perpetual and will not be revoked.
This document and the information contained herein is provided "AS IS" and ALL WARRANTIES, EXPRESS OR IMPLIED are DISCLAIMED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.