JSON-RPC (JavaScript Object Notation – Remote Procedure Call) is a lightweight remote procedure call protocol that uses JSON for encoding messages. It allows a client to call functions (methods) on a remote server as if they were local functions.
Unlike REST, which is resource-oriented, JSON-RPC is procedure-oriented: the client explicitly calls a named method and passes parameters.
JSON-RPC is:
The current widely used version is JSON-RPC 2.0. https://www.jsonrpc.org/specification
A JSON-RPC request is a JSON object with the following fields:
Example request:
{ "jsonrpc": "2.0", "method": "add", "params": [5, 7], "id": 1 }
Successful response:
{ "jsonrpc": "2.0", "result": 12, "id": 1 }
Error response:
{ "jsonrpc": "2.0", "error": { "code": -32601, "message": "Method not found" }, "id": 1 }
If the client sends a request without an id, it becomes a notification.
The server must NOT send a response.
Example:
{ "jsonrpc": "2.0", "method": "logEvent", "params": {"event": "started"} }
JSON-RPC supports sending multiple requests in one array:
[ {"jsonrpc": "2.0", "method": "add", "params": [1,2], "id": 1}, {"jsonrpc": "2.0", "method": "subtract", "params": [5,3], "id": 2} ]
In this section, we implement a simple JSON-RPC server and client using Python.
We will use:
Install dependencies:
pip install flask requests
Create a file: server.py
from flask import Flask, request, jsonify
app = Flask(__name__)
# available RPC methods
def add(a, b):
return a + b
def subtract(a, b):
return a - b
methods = {
"add": add,
"subtract": subtract,
}
@app.route("/rpc", methods=["POST"])
def rpc():
data = request.get_json()
if data.get("jsonrpc") != "2.0":
return jsonify(
{
"jsonrpc": "2.0",
"error": {"code": -32600, "message": "Invalid Request"},
"id": data.get("id"),
}
)
method_name = data.get("method")
params = data.get("params", [])
request_id = data.get("id")
if method_name not in methods:
return jsonify(
{
"jsonrpc": "2.0",
"error": {"code": -32601, "message": "Method not found"},
"id": request_id,
}
)
try:
result = methods[method_name](*params)
return jsonify(
{
"jsonrpc": "2.0",
"result": result,
"id": request_id,
}
)
except Exception as e:
return jsonify(
{
"jsonrpc": "2.0",
"error": {"code": -32603, "message": str(e)},
"id": request_id,
}
)
if __name__ == "__main__":
app.run(port=5000)
Run:
python server.py
Create a file: client.py
import requests import json
url = "http://localhost:5000/rpc"
payload = {
"jsonrpc": "2.0",
"method": "add",
"params": [10, 15],
"id": 1
}
response = requests.post(url, json=payload)
print("Status:", response.status_code)
print("Response:", response.json())
Expected output:
Status: 200 Response: {'jsonrpc': '2.0', 'result': 25, 'id': 1}
| Code | Meaning |
|---|---|
| -32700 | Parse error |
| -32600 | Invalid Request |
| -32601 | Method not found |
| -32602 | Invalid params |
| -32603 | Internal error |