JSON RPC
偶然在 aria2 上看到了这个协议,平时我们都是用json来交换数据的,那么json RPC 是什么。
无状态且轻量级的远程过程调用(RPC)传送协议,其传递内容透过 JSON 为主。
相较于一般的 REST 透过网址(如 GET /user)调用远程服务器,JSON-RPC 直接在内容中定义了欲调用的函数名称(如 {“method”: “getUser”}),
这也令开发者不会陷于该使用 PUT 或者 PATCH 的问题之中。
我的看法
目前国内行业中普遍都是采用特别偷懒或不合理的做法
- 请求全部使用 POST
- 响应 永远都是 HTTP 200
- 响应体里 一定要包装一层,而且有自己的错误码(好像也没人看/维护这个错误码)
在我看完 Json RPC 之后,我的评价是,直接解决国内开发问题
- 请求全部使用 POST,jsonprc: 只有一个 POST 接口, 所谓的接口安全 直接解决
- 响应 永远都是 HTTP 200:json rpc 定义了一部分错误码,而且和 http 的 status 完全错开 并且差异很大,这太棒了
- 响应体里 一定要包装一层,而且有自己的错误码: 请求体和响应体都是固定格式包一层的
此外的优点:
- 异构,不管是什么语言,只要能发http请求,都能上
- 无状态
- json 传输
- 不需要额外的组建和编译过程(轻量)
- 不依赖某个特定的传输协议
太完美了。国内开发的福音啊 完全是。但是 为什么没有普及 我也是很难理解。。。
Code Sample
python ver.
Server side
依赖:
- flask
pip install flask
- flask
pip install jsonrpc
import json
from flask import Flask, request
from jsonrpc import JSONRPCResponseManager, dispatcher
app = Flask(__name__)
@app.route("/")
def hello():
return {"status": "UP"}
@app.route("/jsonrpc", methods=['POST'])
def application():
# Dispatcher is dictionary {<method_name>: callable}
dispatcher["echo"] = lambda s: s
dispatcher["add"] = lambda a, b: a + b
// get json(but dict type)
payload = request.get_json()
// if null return error.
if (payload == None):
return {"error": {"code": 0, "message": "Request error"}, "id": 0, "jsonrpc": "2.0"}
// json.dumps to json, then handle it.
response = JSONRPCResponseManager.handle(json.dumps(payload), dispatcher)
return response.json
@dispatcher.add_method
def foobar(**kwargs):
return kwargs["foo"] + kwargs["bar"]
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
Client Side
import http.client
import json
def main():
# Example echo method
payload = {
"method": "foobar",
"params": {"foo": "json", "bar": "-rpc"},
"jsonrpc": "2.0",
"id": 3,
}
json_data = json.dumps(payload)
headers = {'Content-type': 'application/json'}
http_connection = http.client.HTTPConnection(host="localhost", port=8000)
http_connection.request(url="/jsonrpc", body=json_data, method= "POST" ,headers= headers)
resp = http_connection.getresponse()
print(resp.read().decode())
if __name__ == "__main__":
main()
overall
Json RPC 是一个很好的协议,我希望在将来能够看到国内“大厂”普遍使用,我自己的某部分应用再接下来也会开始使用。