#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
, по-видимому, является ключом к поиску решения здесь.