在微信小程序中调用odoo的jsonrpc

最近的项目中同事碰到了一个需求,需要在微信小程序中以jsonrpc的方式调用odoo接口,虽然odoo已经有了很多其他语言的类库,但是微信还是没有的,虽然微信的主要语言是js但是如果要引入npm的odoo库也是比较大,不是什么好的方案。这里推荐,如果可以使用restful的方式就不要用jsonrpc,因为相对jsonrpc,restful要简便很多。

odoo的web工作方式是基于jsonrpc 2.0,打开chrome的控制台,能够看到很多诸如下面代码的请求。

1
{"jsonrpc":"2.0","method":"call","params":{"model":"shop.user","method":"read","args":[[1],["password","tel","name","owner_wechat","identity_type","identity_image","identity_image2","own_role","identity_id","address","display_name","__last_update"]],"kwargs":{"context":{"lang":"zh_CN","tz":false,"uid":1,"params":{"action":255},"bin_size":true}}},"id":112048255}

这就是jsonrpc的基本样子,那么什么是jsonrpc呢?

JsonRpc

简单说,jsonrpc就是使用json格式远程调用的一种协议。一般包含四个参数,
jsonrpc:版本,
method:方法,
params:参数,
id:id

具体可以参考官方文档

在微信小程序中使用jsonrpc

微信已经封装好了请求方法wx.request,在微信小程序使用jsonrpc 利用wx.request足矣。

认证和请求原理

与odoo web不同,web界面使用请求是http格式,而我们在小程序中使用的是json。web的请求入口时/web/login。json请求的认证入口应该是/web/session/authenticate。

认证需要的参数是db,login,password,认证通过以后返回的结果中会有一个session_id,将session_id存储在缓存中,然后之后的请求头中加入cookie,就可以完成认证请求,直到session过期,再次更新session。

参考代码

认证代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
wx.request({
url: 'https://xxx.com/web/session/authenticate',
method: 'POST',
data: {
jsonrpc: "2.0",
method: "call",
params: {
'db': 'xxx',
'login': 'admin',
'password': 'xxx'
}
},
header: {
'content-type': 'application/json'
},
success: function (res) {
var session = res.data.result.session_id
wx.setStorage({
key: 'cookie',
data: "session_id="+session,
})
}
})

认证完成后,发起业务请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
wx.getStorage({
key: 'cookie',
success: function (res) {
// 请求demo
console.log('****')
console.log(res)
wx.request({
url: 'https://xxx/web/dataset/call_kw/shop.user/write',
method: 'POST',
header: {
'content-type': 'application/json',
'cookie': res.data,
'x-requested-with': 'XMLHttpRequest'
},
data: {
jsonrpc: "2.0",
method: "call",
params: {
"model": "shop.user",
"method": "write",
"args": [[1], { "name": "sss" }],
"kwargs": { "context": { "lang": "zh_CN", "tz": false, "uid": 1, "params": { "action": 255 } } }
}
},
success: function (rex) {
console.log(rex)
}
})
},
})