Enable Dark Mode!
how-to-create-http-json-rpc-and-json-2-controllers-in-odoo-20.jpg
By: Vishnu P

How to Create HTTP, JSON-RPC and JSON-2 Controllers in Odoo 20

Technical Odoo 20 Odoo Community Odoo Enterprises

Controllers in Odoo 20 provide an intermediary link between the external client (for instance, a web browser, a mobile application, or some other program) and the Odoo server. Controllers are Python functions accessible via a certain URL; therefore, they allow serving web pages, sending and receiving data from other applications.

In this article, we will explore three types of controllers in Odoo 20: HTTP, JSON-RPC and JSON-2. We will discuss their usage, providing examples.

1. HTTP Controller

It is the most common one. This is used for rendering web pages, file uploads, and webhooks, such as a landing page, contact form, or "About us" page.

Key parameters:

  • route: The path of the controller function on the URL.
  • type='http': An HTTP type route.
  • auth: The authentication required.
    • public: anyone, including visitors who are not logged in.
    • user: a logged-in user only.
    • bearer: an API key sent in the request header. The request runs with the rights of the key's owner.
    • none: no user or database access. Rarely used in custom modules.
  • website: set to True to use the website theme, header, and footer.
  • methods: the allowed HTTP verbs, such as ['GET'] or ['POST'].
  • csrf: CSRF protection. Set it to False only for external calls that cannot send a token, such as webhooks.
from odoo import http
from odoo.http import request

class MyWebsiteController(http.Controller):
   @http.route('/hello', type='http', auth='public', website=True)
   def hello_world(self, **kwargs):
       return "<h1>Hello, World!</h1>"

Access /hello in your browser, and the web page appears.

Another HTTP route could return JSON, which is useful for basic REST-like APIs:
class PartnerApi(http.Controller):
   @http.route('/api/partners', type='http', auth='user', methods=['GET'], csrf=False)
   def get_partners(self, **kwargs):
       partners = request.env['res.partner'].search_read([], ['id', 'name'], limit=10)
       return request.make_json_response({'status': 'success', 'data': partners})

Example:

The health_check route defined in addons/web/controllers/home.py is an actual HTTP controller that produces JSON data.

@route('/web/health', type='http', auth='none', save_session=False)
def health(self, db_server_status=False):
   health_info = {'status': 'pass'}
   # ... checks the database connection when db_server_status is set ...
   data = json.dumps(health_info)
   headers = [('Content-Type', 'application/json'),
              ('Cache-Control', 'no-store')]
   # ... builds and returns the response ...

2. JSON-RPC controller

The use of JSON-RPC allows JSON data to be exchanged between the frontend and the backend. The JavaScript code can invoke a Python function without refreshing the page, which is useful for loading data and form submission.

Key parameter:

  • type="jsonrpc": Odoo takes care of the JSON serialization/deserialization for you. This type was called json in earlier versions of Odoo.
from odoo import http
from odoo.http import request
class MyJsonController(http.Controller):
@http.route('/my/test/json', type='jsonrpc', auth='user')
def my_json_method(self, **kwargs):
    return {'message': 'JSON response'}

Request body:

{

  "jsonrpc": "2.0",

  "method": "call",

  "params": {}

}

Response:

{

  "jsonrpc": "2.0",

  "result": {"message": "JSON response"}

}

These keys within params will be used to pass keyword arguments to your function. Note that the params must be a JSON object and not a list.

To call it from JavaScript in Odoo:

import { rpc } from "@web/core/network/rpc";
const result = await rpc("/my/test/json", {});
console.log(result.message);

Example:

The web client uses a jsonrpc route for calling methods of the model. It is call_kw in addons/web/controllers/dataset.py.

@http.route(['/web/dataset/call_kw', '/web/dataset/call_kw/<path:path>'], type='jsonrpc', auth="user", readonly=_call_kw_readonly)
def call_kw(self, model, method, args, kwargs, path=None):
   if path != f'{model}.{method}':
       threading.current_thread().rpc_model_method = f'{model}.{method}'
   return call_kw(request.env[model], method, args, kwargs)

3. JSON-2 Controller

JSON-2 is one of the route types of Odoo 20, along with the 'http' and 'jsonrpc'. Odoo has used this route type for its own external API on the /json/2 endpoint, and you can use it in your own custom modules as well.

Key parameter:

  • Type='json2': The JSON object is passed as keyword arguments in your method, while your response will be directly returned as plain JSON. In contrast to the jsonrpc, it does not have any JSON-RPC wrapper.
from odoo import http
from odoo.http import request

class PartnerApi(http.Controller):
   @http.route('/api/partner/<int:partner_id>', type='json2', auth='bearer',
               bearer_scope='rpc', methods=['POST'])
   def partner_info(self, partner_id, **kwargs):
       partner = request.env['res.partner'].browse(partner_id)
       if not partner.exists():
           raise request.not_found('Partner not found')
       return {'id': partner.id, 'name': partner.name, 'email': partner.email}

auth='bearer': The caller provides the API key, and your request is executed under the privileges of the owner of the key. You can generate the key from your Settings > Account Security section. Odoo displays it only once.

Calling the route:

curl -X POST http://localhost:8069/api/partner/7 \

-H "Authorization: bearer YOUR_API_KEY" \

-H "X-Odoo-Database: mydb" \

-H "Content-Type: application/json" \

-d '{}'

The X-Odoo-Database header is needed only when the server has several database

Example:

The built-in /json/2/<model>/<method> endpoint, in addons/rpc/controllers/json2.py, is a json2 controller too.

@http.route(
   '/json/2/<__model__>/<__method__>',
   methods=['POST'],
   auth='bearer',
   bearer_scope='rpc',
   type='json2',
   readonly=_web_json_2_rpc_readonly,
   save_session=False,
)
def web_json_2_rpc(self, __model__, __method__, ids=(), ycontext=frozendict(), **kwargs):
   Model = request.env[__model__].with_context(context)
   func = get_public_method(Model, __method__)
   records = Model.browse(ids)
   result = func(records, **kwargs)
   if isinstance(result, BaseModel):
       result = result.ids
   return result

Due to this controller, any public function of a model can be accessed by other applications without creating any specific controller for them.

curl -X POST http://localhost:8069/json/2/res.partner/search_read \

-H "Authorization: bearer YOUR_API_KEY" \

-H "X-Odoo-Database: mydb" \

-H "Content-Type: application/json" \

-d '{"domain": [["is_company", "=", true]], "fields": ["name"], "limit": 5}'

In order to do that, you have to create a public function in a model. All functions that have an underscore prefix will not be accessible externally.

In Odoo 20, for creating pages, files, and webhooks, use HTTP controllers, while for JSON-RPC custom calls from your frontend, use JSON-RPC controllers. For accessing the Odoo API from any other external system with an API key, use the JSON-2 API.

To read more about Overview of JSON-RPC Controller in Odoo 19, refer to our blog, Overview of JSON-RPC Controller in Odoo 19.


Frequently Asked Questions

When to use HTTP controller vs a JSON controller?

HTTP controller (type='http') – use it to render a web page, download a file, or handle a webhook. JSON controller (jsonrpc or json2) – if you just want to exchange data between your frontend or other app.

Can I disable CSRF protection in my route?

Only for requests coming from outside which could not pass a CSRF token (for example webhooks or requests from other systems). Do not turn it off on routes served via browser in the logged-in session.

What does auth='public' mean?

It says that this route will be accessible by everyone. Use only for routes that should be available to all users. Use auth='user' if the user should be logged in.

If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



WhatsApp