在odoo中使用Swagger

感谢OCA为我们提供了基础模块

做后台的同学一定听说过swagger的大名,现在改名叫OpenApi了,简单说就是一个提供了方便测试的接口界面。跟我们做对接的人,打开界面就能轻松地知道如何正确的调用我们的接口和接收返回值。

网上比较多的是flask和swagger结合的例子,如果我们想要在odoo中实现类似的REST Swagger模式,我们可以按照下面的方式进行。

安装依赖

本文依赖于OCA的一个模块base_rest,读者可以自行搜索,也可以关注odoohub回复base_rest获取下载链接。

编写接口

由于odoo自带的jsonrpc并不能满足我们的需求(我们不可能给第三方系统的人提供一种类似res.partner的对象,并给他们解释对象的意思),因此,我们需要重新定义一些业务接口。

定义一个新的Service

我们把新的API接口定义为一个Service,继承base.rest.service这个对象,并定义好usage、description等属性。

1
2
3
4
5
6
7
8
class AladinService(Component):
_inherit = "base.rest.service"
_name = "aladin.service"
_usage = "Aladin"
_collection = "base.rest.aladin.services"
_description = """
阿拉丁业务API
"""

定义接口

rest_api借助cerberus(Cerberus是一个用于Python的轻量级且可扩展的数据验证库)来验证我们输入的字段值。

一个典型的get接口可以写成下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@skip_secure_response
def get(self, _id, size):
"""
Get partner's image
"""
field = "image"
if size == "small":
field = "image_small"
elif size == "medium":
field = "image_medium"
status, headers, content = self.env["ir.http"].binary_content(
model="res.partner", id=_id, field=field, env=self.env
)
if not content:
raise MissingError(_("No image found for partner %s") % _id)
image_base64 = base64.b64decode(content)
headers.append(("Content-Length", len(image_base64)))
response = request.make_response(image_base64, headers)
response.status_code = status
return response

其中方法的描述会自动加载到swagger的方法描述中。

定义API路径

在controller中,定义API接口的路径:

1
2
3
4
class BaseRestDemoPrivateApiController(main.RestController):
_root_path = "/base_rest_demo_api/private/"
_collection_name = "base.rest.demo.private.services"
_default_auth = "user"

base_rest提供了基本的权限认证,基于odoo自身的账户设置。_default_auth的可选值有public和user。两个值会被加载到controller的auth参数中,以用来标识验证方法。

这并非当前流行的验证方式,可惜的是oca并没有提供oatuh的验证机制。因此,笔者在实际的应用过程中,借鉴了另外的一个模块restapi的方式。

页面展示

安装模块后,我们可以在Odoo中的模块界面中看到一个swagger的图标:

点击进入swagger api界面:

你的支持我的动力