Search 1.9 billion lines of Odoo code on GitHub

demo_controller_api_http

Author: My Company
License: no license
Branch: 15.0
Repository: twtrubiks/odoo-demo-addons-tutorial
Dependencies: web
Languages: Markdown (156, 55.9%), and Python (123, 44.1%)

<h1>odoo 15 教學 - 透過 controller http 建立簡易 REST API</h1> <ul> <li><a href="">(等待新增)Youtube Tutorial - 透過 controller http 建立簡易 REST API</a></li> </ul> <p>之前在 <a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/14.0/demo_controller_json">odoo 14 教學 - 透過 controller 建立簡單 api</a> 這篇文章中,</p> <p>有教大家簡單的透過 controller 建立 api,</p> <p>今天要更進一步, 加上 <code>auth=users</code> 以及透過 <code>http</code> 打造類似 REST API 的範例.</p> <h2>說明</h2> <p>首先把 addons 裝起來,</p> <p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/blob/15.0/demo_controller_api/demo_controller_api_http/controllers/api.py">demo<em>controller</em>api_http/controllers/api.py</a></p> <p>```python from odoo import http, _ from odoo.http import request import json</p> <p>class DemoApiControllerHttp(http.Controller): def get<em>res</em>users(self, pk=None): if pk: domain = [(&quot;id&quot;, &quot;=&quot;, pk)] else: domain = []</p> <pre><code> return [ { &quot;id&quot;: record.id, &quot;name&quot;: record.name, &quot;company&quot;: record.company_id.name, &quot;phone&quot;: record.phone, &quot;email&quot;: record.email, } for record in request.env[&quot;res.users&quot;].sudo().search(domain) ] @http.route(&quot;/api/users/&lt;string:pk&gt;&quot;, methods=[&quot;GET&quot;], type=&quot;http&quot;, auth=&quot;user&quot;, csrf=False) def api_get_res_users(self, pk=None): return json.dumps(self.get_res_users(pk)) @http.route(&quot;/api/users/&quot;, methods=[&quot;GET&quot;], type=&quot;http&quot;, auth=&quot;user&quot;, csrf=False) def api_get_res_user(self): return json.dumps(self.get_res_users()) @http.route(&quot;/api/users/&quot;, methods=[&quot;POST&quot;], type=&quot;http&quot;, auth=&quot;user&quot;, csrf=False) def api_post_res_user(self): param = request.params if not param[&quot;login&quot;]: return json.dumps(&quot;login not allow empty&quot;) vals = { &quot;name&quot;: param[&quot;name&quot;], &quot;phone&quot;: param[&quot;phone&quot;], &quot;email&quot;: param[&quot;email&quot;], &quot;login&quot;: param[&quot;login&quot;], } if request.env[&quot;res.users&quot;].sudo().search([(&quot;login&quot;, &quot;=&quot;, param[&quot;login&quot;])]): return json.dumps(&quot;user already exists&quot;) res_user = request.env[&quot;res.users&quot;].sudo().create(vals) return json.dumps(self.get_res_users(res_user.id)) @http.route(&quot;/api/users/&lt;string:pk&gt;&quot;, methods=[&quot;PATCH&quot;], type=&quot;http&quot;, auth=&quot;user&quot;, csrf=False) def api_patch_res_user(self, pk=None): param = request.params res_user = request.env[&quot;res.users&quot;].sudo().search([(&quot;id&quot;, &quot;=&quot;, pk)]) if not res_user: return json.dumps(&quot;user not exists&quot;) res_user.phone = param[&quot;phone&quot;] return json.dumps(self.get_res_users(pk)) </code></pre> <p>```</p> <p>這邊和 <a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/15.0/demo_controller_api/demo_controller_api_jsonrpc">demo<em>controller</em>api_jsonrpc</a> 比較不同的地方有幾個,</p> <p>首先是改成了 <code>type=&quot;http&quot;</code>, 然後加上了 <code>csrf=False</code>, 因為 odoo 定義</p> <p><code>text * if the form is accessed by an external third party (e.g. REST API endpoint, payment gateway callback) you will need to disable CSRF protection (and implement your own protection if necessary) by passing the `csrf=False` parameter to the `route` decorator. </code></p> <p>這邊主要建立了幾個 api, 分別是</p> <p><code>GET</code> <code>/api/users/</code> 取得全部 <code>res_users</code>.</p> <p><code>GET</code> <code>/api/users/&lt;string:pk&gt;</code> 取得特定 <code>res_users</code>.</p> <p><code>POST</code> <code>/api/users/</code> 新增 <code>res_users</code>.</p> <p><code>PATCH</code> <code>/api/users/&lt;string:pk&gt;</code> 修改特定 <code>res_users</code> 資料.</p> <h2>client 端</h2> <p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/blob/15.0/demo_controller_api/demo_controller_api_http/client.py">client.py</a> 端的部份就是直接執行</p> <p><code>cmd python3 client.py </code></p> <p>執行畫面, 這邊用 <code>get_users()</code> 示範,</p> <p><img src="https://i.imgur.com/At4wBFy.png" alt="alt tag"></p> <p>```python import requests import json</p> <p>HOST = &quot;http://0.0.0.0:8069&quot; AUTH_URL = &quot;{}/web/session/authenticate/&quot;.format(HOST)</p> <p>headers = { &quot;Content-Type&quot;: &quot;application/json&quot;, &quot;Accept&quot;: &quot;application/json&quot;, }</p> <p>session_data = { &quot;jsonrpc&quot;: &quot;2.0&quot;, &quot;params&quot;: { &quot;login&quot;: &quot;admin&quot;, &quot;password&quot;: &quot;admin&quot;, &quot;db&quot;: &quot;odoo&quot;, }, }</p> <p>def get<em>session</em>id(): res = requests.post(AUTH<em>URL, data=json.dumps(session</em>data), headers=headers) return res.cookies[&quot;session_id&quot;]</p> <p>def get<em>users(): base</em>url = &quot;{}/api/users/&quot;.format(HOST)</p> <pre><code>res = requests.get( base_url, cookies={&quot;session_id&quot;: get_session_id()}, ) print(res.json()) </code></pre> <p>def get<em>user(): base</em>url = &quot;{}/api/users/3/&quot;.format(HOST)</p> <pre><code>res = requests.get( base_url, cookies={&quot;session_id&quot;: get_session_id()}, ) print(res.json()) </code></pre> <p>def add<em>user(): base</em>url = &quot;{}/api/users/&quot;.format(HOST) param = { &quot;login&quot;: &quot;test<em>user&quot;, &quot;name&quot;: &quot;test</em>user&quot;, &quot;phone&quot;: &quot;00000&quot;, &quot;email&quot;: &quot;xxx@test.com&quot;, }</p> <pre><code>res = requests.post( base_url, data=param, cookies={&quot;session_id&quot;: get_session_id()}, ) print(res.json()) </code></pre> <p>def edit<em>user(): base</em>url = &quot;{}/api/users/3/&quot;.format(HOST) param = { &quot;phone&quot;: &quot;0000000000&quot;, }</p> <pre><code>res = requests.patch( base_url, data=param, cookies={&quot;session_id&quot;: get_session_id()}, ) print(res.json()) </code></pre> <p>if <strong>name</strong> == &quot;<strong>main</strong>&quot;: get<em>users() # get</em>user() # add<em>user() # edit</em>user() ```</p> <p>odoo 整個流程是要先取得 <code>session_id</code>(對 <code>/web/session/authenticate/</code> 發送請求),</p> <p>( 請輸入正確的 db, login, password, host )</p> <p><code>/web/session/authenticate/</code> 還是需要使用 <code>jsonrpc</code> 的方式呼叫,</p> <p>原因是 <code>addons/web/controllers/main.py</code> 底下的定義就是 <code>type=&#39;json&#39;</code>,</p> <p>```python class Session(http.Controller):</p> <pre><code>...... @http.route(&#39;/web/session/authenticate&#39;, type=&#39;json&#39;, auth=&quot;none&quot;) def authenticate(self, db, login, password, base_location=None): request.session.authenticate(db, login, password) return request.env[&#39;ir.http&#39;].session_info() </code></pre> <p>```</p> <p>再去發送對應的 api ( 這邊都是使用 <code>http</code> 的方式 ).</p>