Как я могу обрабатывать произвольные входящие HTTP-запросы `application / json` в Odoo?

#http #odoo

Вопрос:

Я хотел бы принимать и отвечать на запросы JSON в Odoo из источников, которые могут быть вне моего контроля. Причина, по которой это не так просто, заключается в том, что Odoo заставляет меня использовать JSON-RPC, который не подходит для источника, с которым я взаимодействую.

Например, если я задаю тип маршрута http в @http.route декораторе, Odoo отклоняет запрос, если mimetype application/json равен, но в теле нет содержимого. В моем случае это не сработает, потому что я, возможно, не смогу выбрать, что мне отправляет другой источник. Кроме того, я не могу отправить пользовательский ответ JSON, если только входящий запрос не имеет application/json mimetype, который опять же не находится под моим контролем.

Я много искал в Интернете и прочитал большую часть исходного кода HTTP Odoo. «Решение», которое я продолжаю видеть повсюду, — это обезьянье исправление JsonRequest класса тем или иным способом. Это позволяет мне действительно отвечать тем, что я хочу, однако это не позволяет мне принимать все, что может отправить мне служба.

Один конкретный случай, который мне нужно уметь обрабатывать, — это входящие application/json запросы GET без тела. Как я могу добиться этого, несмотря на жесткую передачу Odoo JSON-RPC?

Ответ №1:

Для этого нет правильного способа, я бы назвал описанный метод приемлемым. Это относится к версиям Odoo с 10 по 15.

На мой взгляд, было бы лучше оставить класс JSONRequest в покое и позволить ему выполнять свою работу, связанную с 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)
 

Этот момент кажется наиболее подходящим для исправления, возвращая объект класса пользовательского запроса из этого метода. Однако есть проблема — этот метод вызывается до обнаружения любого маршрута. Вы должны изобрести подходящий метод, чтобы указать, какой объект класса запроса должен быть возвращен.

Чтобы получить представление о возможной реализации, пожалуйста, ознакомьтесь с модулем OCA base_rest.

Комментарии:

1. Источник OCA base_rest , по-видимому, является ключом к поиску решения здесь.