借助此插件,您可以使用它为Odoo开发高级REST API。
项目描述
此插件提供开发Odoo高级REST API的基础。
随着Odoo成为企业IT系统的核心之一,通常需要设置专门的接口,以便现有系统可以与Odoo交互。
尽管Odoo的XML-RPC接口在这种情况下很有用,但它需要深入了解Odoo的内部数据模型。当广泛使用时,它会在Odoo内部和客户端系统之间创建强烈的耦合,从而增加维护成本。
一旦开发完成,将从源代码生成一个OpenApi文档,并通过您的odoo服务器在https://my_odoo_server/api-docs上提供的Swagger UI提供。
目录
配置
在Odoo启动时加载此模块,包括在您的服务器配置文件中
server_wide_modules=base,web,base_rest
如果在调用服务方法(例如,缺少参数)时发生错误,系统将仅返回问题的通用描述而不提供详细信息。这是故意为之,以确保对实现细节的透明度最大,从而降低安全问题的风险。
当开发中的外部系统访问服务时,这种限制可能会带来问题。要知道错误的详细信息,确实需要访问服务器的日志。并不是总是可以提供这种访问。这就是为什么你可以配置服务器以开发模式运行这些服务。
要在开发模式下运行REST API,必须在服务器配置文件中添加一个名为“[base_rest]”的新部分,并使用选项“dev_mode=True”。
[base_rest]
dev_mode=True
当REST API以开发模式运行时,在出现错误的情况下,会返回原始描述和堆栈跟踪。**请注意,不要在生产环境中使用此模式**。
使用方法
要添加自己的REST服务,你必须提供至少2个类。
一个提供服务业务逻辑的组件,
一个用于注册服务的控制器。
你的服务业务逻辑必须实现到一个继承自(odoo.addons.component.core.Component)的组件中。
最初,base_rest默认公开服务中定义的所有公共方法。通过HTTP访问方法的约定如下
如果定义了方法def get(self, _id),则可以通过HTTP GET路由<string:_service_name>/<int:_id>和<string:_service_name>/<int:_id>/get访问。
如果定义了方法def search(self, **params),则可以通过HTTP GET路由<string:_service_name>/和<string:_service_name>/search访问。
如果定义了方法def delete(self, _id),则可以通过HTTP DELETE路由<string:_service_name>/<int:_id>访问。
如果定义了方法def update(self, _id, **params),则可以通过HTTP PUT路由<string:_service_name>/<int:_id>访问。
其他方法只能通过HTTP POST路由<string:_service_name>或<string:_service_name>/<string:method_name>或<string:_service_name>/<int:_id>或<string:_service_name>/<int:_id>/<string:method_name>访问。
from odoo.addons.component.core import Component
class PingService(Component):
_inherit = 'base.rest.service'
_name = 'ping.service'
_usage = 'ping'
_collection = 'my_module.services'
# The following method are 'public' and can be called from the controller.
def get(self, _id, message):
return {
'response': 'Get called with message ' + message}
def search(self, message):
return {
'response': 'Search called search with message ' + message}
def update(self, _id, message):
return {'response': 'PUT called with message ' + message}
# pylint:disable=method-required-super
def create(self, **params):
return {'response': 'POST called with message ' + params['message']}
def delete(self, _id):
return {'response': 'DELETE called with id %s ' % _id}
# Validator
def _validator_search(self):
return {'message': {'type': 'string'}}
# Validator
def _validator_get(self):
# no parameters by default
return {}
def _validator_update(self):
return {'message': {'type': 'string'}}
def _validator_create(self):
return {'message': {'type': 'string'}}
一旦实现了你的服务(ping,…),你必须告诉Odoo如何访问这些服务。这个过程通过实现一个继承自(odoo.addons.base_rest.controllers.main.RestController)的控制器来完成。
from odoo.addons.base_rest.controllers import main
class MyRestController(main.RestController):
_root_path = '/my_services_api/'
_collection_name = my_module.services
在你的控制器中,_‘root_path’用于指定访问服务的路径根,而‘_collection_name’是提供请求服务业务逻辑的集合名称。
通过继承自(RestController),以下路由将被注册以访问你的服务
@route([
ROOT_PATH + '<string:_service_name>',
ROOT_PATH + '<string:_service_name>/search',
ROOT_PATH + '<string:_service_name>/<int:_id>',
ROOT_PATH + '<string:_service_name>/<int:_id>/get'
], methods=['GET'], auth="user", csrf=False)
def get(self, _service_name, _id=None, **params):
method_name = 'get' if _id else 'search'
return self._process_method(_service_name, method_name, _id, params)
@route([
ROOT_PATH + '<string:_service_name>',
ROOT_PATH + '<string:_service_name>/<string:method_name>',
ROOT_PATH + '<string:_service_name>/<int:_id>',
ROOT_PATH + '<string:_service_name>/<int:_id>/<string:method_name>'
], methods=['POST'], auth="user", csrf=False)
def modify(self, _service_name, _id=None, method_name=None, **params):
if not method_name:
method_name = 'update' if _id else 'create'
if method_name == 'get':
_logger.error("HTTP POST with method name 'get' is not allowed. "
"(service name: %s)", _service_name)
raise BadRequest()
return self._process_method(_service_name, method_name, _id, params)
@route([
ROOT_PATH + '<string:_service_name>/<int:_id>',
], methods=['PUT'], auth="user", csrf=False)
def update(self, _service_name, _id, **params):
return self._process_method(_service_name, 'update', _id, params)
@route([
ROOT_PATH + '<string:_service_name>/<int:_id>',
], methods=['DELETE'], auth="user", csrf=False)
def delete(self, _service_name, _id):
return self._process_method(_service_name, 'delete', _id)
因此,对“http://my_odoo/my_services_api/ping”的HTTP GET调用将被调度到方法PingService.search。
除了轻松公开你的方法外,该模块还允许你定义必须符合的数据模式。这些模式基于Cerberus schemas定义,并使用以下命名约定关联到方法。
对于方法my_method,将调用def _validator_my_method(self):以获取验证输入参数所需的模式。
如果定义,将调用def _validator_return_my_method(self):以获取用于验证响应的模式。
为了提供更多的灵活性,已开发了一个新的API。
这个新API通过使用python装饰器显式标记一个方法作为通过REST API可用的方法来替换用于公开服务时使用的隐式方法:odoo.addons.base_rest.restapi.method。
class PartnerNewApiService(Component):
_inherit = "base.rest.service"
_name = "partner.new_api.service"
_usage = "partner"
_collection = "base.rest.demo.new_api.services"
_description = """
Partner New API Services
Services developed with the new api provided by base_rest
"""
@restapi.method(
[(["/<int:id>/get", "/<int:id>"], "GET")],
output_param=restapi.CerberusValidator("_get_partner_schema"),
auth="public",
)
def get(self, _id):
return {"name": self.env["res.partner"].browse(_id).name}
def _get_partner_schema(self):
return {
"name": {"type": "string", "required": True}
}
感谢这个新的API,您现在可以自由指定自己的路由,并且可以将其他对象类型用作方法参数或响应。例如,base_rest_datamodel 允许您将数据模型对象实例用于您的服务。
from marshmallow import fields
from odoo.addons.base_rest import restapi
from odoo.addons.component.core import Component
from odoo.addons.datamodel.core import Datamodel
class PartnerSearchParam(Datamodel):
_name = "partner.search.param"
id = fields.Integer(required=False, allow_none=False)
name = fields.String(required=False, allow_none=False)
class PartnerShortInfo(Datamodel):
_name = "partner.short.info"
id = fields.Integer(required=True, allow_none=False)
name = fields.String(required=True, allow_none=False)
class PartnerNewApiService(Component):
_inherit = "base.rest.service"
_name = "partner.new_api.service"
_usage = "partner"
_collection = "base.rest.demo.new_api.services"
_description = """
Partner New API Services
Services developed with the new api provided by base_rest
"""
@restapi.method(
[(["/", "/search"], "GET")],
input_param=restapi.Datamodel("partner.search.param"),
output_param=restapi.Datamodel("partner.short.info", is_list=True),
auth="public",
)
def search(self, partner_search_param):
"""
Search for partners
:param partner_search_param: An instance of partner.search.param
:return: List of partner.short.info
"""
domain = []
if partner_search_param.name:
domain.append(("name", "like", partner_search_param.name))
if partner_search_param.id:
domain.append(("id", "=", partner_search_param.id))
res = []
PartnerShortInfo = self.env.datamodels["partner.short.info"]
for p in self.env["res.partner"].search(domain):
res.append(PartnerShortInfo(id=p.id, name=p.name))
return res
已知问题/路线图
变更日志
12.0.2.0.1
现在,_validator_…() 方法可以返回一个 cerberus Validator 对象,而不是一个模式字典,以提高灵活性(例如,允许验证器选项如 allow_unknown)。
12.0.2.0.0
许可证从 AGPL-3 更改为 LGPL-3
12.0.1.0.1
修复了在REST API的方法部分未提供文档时渲染jsonapi文档的问题。
12.0.1.0.0
第一个官方版本。该插件已孵化到 Akretion 的 Shopinvader 存储库。有关更多信息,请查看 git 日志。
错误追踪器
错误在 GitHub Issues 上跟踪。如果遇到问题,请检查是否已经报告了您的问题。如果您是第一个发现它的,请通过提供详细和受欢迎的 反馈 来帮助我们解决它。
请不要直接联系贡献者寻求支持或帮助解决技术问题。
致谢
贡献者
Laurent Mignon <laurent.mignon@acsone.eu>
Sébastien Beau <sebastien.beau@akretion.com>
维护者
本模块由OCA维护。
OCA,即Odoo社区协会,是一个非营利组织,其使命是支持Odoo功能的协作开发并促进其广泛使用。
当前 维护者
本模块是GitHub上 OCA/rest-framework 项目的一部分。
欢迎您贡献力量。有关如何贡献的更多信息,请访问 https://odoo-community.org/page/Contribute。
项目详情
哈希值 for odoo12_addon_base_rest-12.0.3.1.0-py3-none-any.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bd72705f75b458d0e5bb9a6dbe5d39313f5d135cb852d6edd08dd8a2702263ca |
|
MD5 | 39fe134574a9090babc9094cf2c9cf5d |
|
BLAKE2b-256 | f115991580fdab6c68eb29ddc68f73989e780e4a5d521ec682baf30257a6c3ef |