documentation/content/developer/reference/javascript/services/rpc_service.rst
Simon Genin (ges) fd28f72c68 wip
2021-10-12 12:06:37 +02:00

117 lines
3.6 KiB
ReStructuredText

RPC service
===========
.. list-table::
:header-rows: 1
* - Technical name
- Dependencies
* - ``rpc``
- ``notifications``
Overview
--------
The RPC service has a single purpose: send requests to the server. Its external
API is a single function, with the following type:
.. code-block:: ts
type RPC = (route: string, params?: { [key: string]: any }) => Promise<any>;
This makes it easy to use. For example, calling a controller ``/some/route`` can
be done with the following code:
.. code-block:: ts
class MyComponent extends Component {
rpc = useService("rpc");
async someMethod() {
const result = await this.rpc("/some/route");
}
}
Note that the ``rpc`` service is considered a low-level service. It should only be
used to interact with Odoo controllers. To work with models (which is by far the
most important usecase), one should use the `\ ``model`` <model.md>`_ service instead.
Calling a controller
--------------------
As explained in the overview, calling a controller is very simple. The route
should be the first argument, and optionally, a ``params`` object can be given as
a second argument.
.. code-block:: ts
const result = await this.rpc("/my/route", { some: "value" });
Technical notes
---------------
* The ``rpc`` service communicates with the server by using a ``XMLHTTPRequest`` object,
configured to work with ``application/json`` content type.
* So clearly the content of the request should be JSON serializable.
* Each request done by this service uses the ``POST`` http method
* Server errors actually return the response with an http code 200. But the ``rpc``
service will treat them as error (see below)
Error Handling
--------------
An rpc can fail for two main reasons:
* either the odoo server returns an error (so, we call this a ``server`` error).
In that case the http request will return with am http code 200 BUT with a
response object containing an ``error`` key.
* or there is some other kind of network error
When a rpc fails, then:
* the promise representing the rpc is rejected, so the calling code will crash,
unless it handles the situation
*
an event ``RPC_ERROR`` is triggered on the main application bus. The event payload
contains a description of the cause of the error:
If it is a server error (the server code threw an exception). In that case
the event payload will be an object with the following keys:
* ``type = 'server'``
* ``message(string)``
*
``code(number)``
*
``name(string)`` (optional, used by the crash manager to look for an appropriate
dialog to use when handling the error)
* ``subType(string)`` (optional, often used to determine the dialog title)
* ``data(object)`` (optional object that can contain various keys among which
``debug`` : the main debug information, with the call stack)
If it is a network error, then the error description is simply an object
``{type: 'network'}``.
When a network error occurs, a notification is displayed and the server is regularly
contacted until it responds. The notification is closed as soon as the server responds.
Specialized behaviour for components
------------------------------------
The ``rpc`` service has a specific optimization to make using it with component safer. It
does two things:
* if a component is destroyed at the moment an rpc is initiated, an error will
be thrown. This is considered an error, a destroyed component should be inert.
* if a component is destroyed when a rpc is completed, which is a normal situation
in an application, then the promise is simply left pending, to prevent any
followup code to execute.