如何在 Odoo 中处理任意传入的 `application/json` HTTP 请求?

How can I handle arbitrary incoming `application/json` HTTP requests in Odoo?

我愿意在 Odoo 中接受并回复 JSON 来自我无法控制的来源的请求。这不是直截了当的原因是因为 Odoo 强迫我使用 JSON-RPC,它不适合我正在与之交互的源。

例如,如果我在 @http.route 装饰器中将路由类型设置为 http,如果 mimetype 是 application/json 但正文没有内容,Odoo 会拒绝请求。这对我来说行不通,因为我可能无法选择其他来源发送给我的内容。此外,我无法发回自定义 JSON 响应,除非传入请求没有 application/json mimetype,这又不在我的控制范围内。

我在互联网上进行了大量搜索,并阅读了很多 Odoo 的 HTTP 源代码。我到处都看到的“解决方案”是以一种或另一种方式对 JsonRequest class 进行猴子修补。这确实让我可以用我想要的任何东西来回应,但是它不允许我接受服务可能发送给我的任何东西。

我需要能够处理的一个特定情况是没有正文的传入 application/json GET 请求。尽管 Odoo 的重手 JSON-RPC 处理,我如何实现这一目标?

没有正确的方法来完成这个,我认为描述的方法是可以接受的。它适用于 Odoo 10 到 15 的版本。

在我看来,最好不要管 JsonRequest class,让它完成 JSON-RPC 相关的工作。 odoo.http.Root.get_request 方法根据内容类型构造 json-rpc 或 http 请求对象:

class Root(object):
    """Root WSGI application for the OpenERP Web Client.
    """
    
    # ...
    
    def get_request(self, httprequest):
        # deduce type of request
        if httprequest.mimetype in ("application/json", "application/json-rpc"):
            return JsonRequest(httprequest)
        else:
            return HttpRequest(httprequest)

这一点似乎是最相关的要修补的点,return通过此方法自定义请求 class 对象。但是有一个问题——这个方法在任何路由检测之前被调用。你必须发明一个合适的方法来告诉,哪个请求 class 反对 return.

要了解可能的实施方式,请参阅 OCA base_rest 模块。