تكامل واجهة برمجة تطبيقات Odoo: دليل REST وJSON-RPC وXML-RPC
يعرض Odoo 19 ثلاث واجهات API تغطي كل شيء بدءًا من استرجاع البيانات البسيطة وحتى أتمتة سير العمل المعقدة. سواء كنت تقوم بإنشاء تطبيق جوال مخصص، أو المزامنة مع نظام أساسي تابع لجهة خارجية، أو توسيع إمكانات Odoo بخدمات صغيرة خارجية، فإن إتقان طبقة Odoo API يعد أمرًا أساسيًا لأي مشروع تكامل جاد.
يقدم هذا الدليل أمثلة على أكواد العمل، وتدفقات المصادقة، والتوصيات المعمارية لعمليات تكامل REST، وJSON-RPC، وXML-RPC — الواجهات الأساسية الثلاث المتوفرة في Odoo 19 Enterprise.
الوجبات الرئيسية
- يوفر Odoo 19 واجهات REST (OpenAPI 3.0)، وJSON-RPC 2.0، وXML-RPC
- تستخدم المصادقة مفاتيح واجهة برمجة التطبيقات (مستحسن) أو تسجيل الدخول المستند إلى الجلسة
- JSON-RPC هي الواجهة الأكثر اكتمالاً للميزات للعمليات المعقدة
- تتبع REST API مواصفات OpenAPI 3.0 وتدعم أفعال HTTP القياسية
- يعتبر XML-RPC قديمًا ولكنه لا يزال مدعومًا بالكامل للتوافق مع الإصدارات السابقة
- يجب تنفيذ تحديد المعدل ومعالجة الأخطاء من جانب العميل
- تعمل خطافات الويب في Odoo 19 على دفع البيانات إلى الأنظمة الخارجية عند تسجيل التغييرات
- تحترم جميع مكالمات واجهة برمجة التطبيقات (API) حقوق الوصول وقواعد التسجيل الخاصة بـ Odoo
مقارنة واجهة API
قبل كتابة سطر واحد من التعليمات البرمجية، اختر واجهة API المناسبة لحالة الاستخدام الخاصة بك:
| ميزة | ريست API | جسون-RPC | XML-RPC |
|---|---|---|---|
| البروتوكول | HTTP/HTTPS | HTTP/HTTPS | HTTP/HTTPS |
| تنسيق الحمولة | جيسون | جيسون | أكس أم أل |
| مواصفات OpenAPI | نعم (اختيال) | لا | لا |
| عمليات الخام | نعم | نعم | نعم |
| استدعاءات الطريقة | محدودة | كامل | كامل |
| مشغلات سير العمل | عبر الإجراءات | عبر Execute_kw | عبر التنفيذ |
| موصى به لـ | عمليات التكامل الجديدة | منطق معقد | الأنظمة القديمة |
| مكتبة بايثون | طلبات | odoo-xmlrpc / طلبات | xmlrpc.client |
متى تستخدم REST: إنشاء تطبيق جوال، أو التكامل مع منصات الويب الأصلية (Shopify، Stripe)، أو عندما يشعر فريقك براحة أكبر مع اتفاقيات REST.
متى يتم استخدام JSON-RPC: تنفيذ أساليب معقدة من جانب خادم Odoo، أو قراءة مجموعات كبيرة من البيانات باستخدام مرشحات النطاق، أو عندما تحتاج إلى الوصول إلى الأساليب التي لم يتم الكشف عنها عبر REST.
متى تستخدم XML-RPC: الحفاظ على عمليات التكامل الحالية التي تم إنشاؤها قبل توفر REST، أو عندما يكون النظام الأساسي الخاص بك يحتوي على مكتبات عملاء XML-RPC ناضجة.
المصادقة
مصادقة مفتاح واجهة برمجة التطبيقات (مستحسن)
يدعم Odoo 19 مصادقة مفتاح API لجميع الواجهات الثلاث. قم بإنشاء مفتاح API ضمن الإعدادات → المستخدمون → المستخدم الخاص بك → مفاتيح واجهة برمجة التطبيقات.
import requests
ODOO_URL = "https://your-odoo.com"
API_KEY = "your_api_key_here"
DATABASE = "your_database"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}"
}
يتم تحديد نطاق مفاتيح واجهة برمجة التطبيقات (API) لمستخدم معين وترث حقوق الوصول الخاصة بهذا المستخدم. قم بإنشاء مستخدمي خدمة مخصصين مع الحد الأدنى من الأذونات المطلوبة لحسابات التكامل.
المصادقة المستندة إلى الجلسة (JSON-RPC / XML-RPC)
بالنسبة إلى JSON-RPC، قم بالمصادقة باستخدام نقطة النهاية /web/dataset/call_kw بعد إنشاء الجلسة:
import requests
import json
session = requests.Session()
# Authenticate
auth_payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"db": "your_database",
"login": "admin",
"password": "your_password"
}
}
response = session.post(
f"{ODOO_URL}/web/session/authenticate",
json=auth_payload
)
uid = response.json()['result']['uid']
print(f"Authenticated as UID: {uid}")
بالنسبة إلى XML-RPC، استخدم المصادقة القياسية المكونة من خطوتين:
import xmlrpc.client
url = "https://your-odoo.com"
db = "your_database"
username = "admin"
password = "your_password"
# Step 1: Get UID
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, username, password, {})
# Step 2: Use UID for subsequent calls
models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
واجهة برمجة تطبيقات REST: OpenAPI 3.0
يقدم Odoo 19 واجهة REST API كاملة مع مواصفات OpenAPI 3.0. قم بالوصول إلى الوثائق التفاعلية على https://your-odoo.com/api/docs.
قائمة السجلات
# GET /api/sale.order — list all sales orders
response = requests.get(
f"{ODOO_URL}/api/sale.order",
headers=headers,
params={
"domain": '[["state", "=", "sale"]]',
"fields": '["name", "partner_id", "amount_total", "state"]',
"limit": 50,
"offset": 0
}
)
orders = response.json()
قراءة سجل واحد
# GET /api/sale.order/{id}
order_id = 123
response = requests.get(
f"{ODOO_URL}/api/sale.order/{order_id}",
headers=headers
)
order = response.json()
إنشاء سجل
# POST /api/sale.order
payload = {
"partner_id": 42,
"order_line": [
{
"product_id": 7,
"product_uom_qty": 5,
"price_unit": 100.0
}
]
}
response = requests.post(
f"{ODOO_URL}/api/sale.order",
headers=headers,
json=payload
)
new_order = response.json()
تحديث السجل
# PATCH /api/sale.order/{id}
response = requests.patch(
f"{ODOO_URL}/api/sale.order/{order_id}",
headers=headers,
json={"note": "Rush order — priority handling required"}
)
حذف السجل
# DELETE /api/sale.order/{id}
response = requests.delete(
f"{ODOO_URL}/api/sale.order/{order_id}",
headers=headers
)
واجهة JSON-RPC
يوفر JSON-RPC إمكانية الوصول إلى واجهة برمجة تطبيقات Odoo Python الكاملة، بما في ذلك الأساليب من جانب الخادم التي لم يتم الكشف عنها عبر REST. نقطة النهاية الأساسية هي /web/dataset/call_kw.
البحث الأساسي والقراءة
def call_kw(model, method, args, kwargs=None):
payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": model,
"method": method,
"args": args,
"kwargs": kwargs or {}
}
}
response = session.post(
f"{ODOO_URL}/web/dataset/call_kw",
json=payload
)
return response.json().get('result')
# Search for confirmed sales orders
order_ids = call_kw(
"sale.order",
"search",
[[["state", "=", "sale"]]],
{"limit": 100, "order": "date_order desc"}
)
# Read specific fields
orders = call_kw(
"sale.order",
"read",
[order_ids],
{"fields": ["name", "partner_id", "amount_total", "date_order"]}
)
قراءة البحث (مدمجة)
orders = call_kw(
"sale.order",
"search_read",
[[["partner_id.country_id.code", "=", "US"]]],
{
"fields": ["name", "partner_id", "amount_total"],
"limit": 50,
"offset": 0,
"order": "amount_total desc"
}
)
إنشاء السجلات
new_id = call_kw(
"sale.order",
"create",
[{
"partner_id": 42,
"order_line": [
(0, 0, {
"product_id": 7,
"product_uom_qty": 10,
"price_unit": 150.0
})
]
}]
)
الاتصال بالطرق من جانب الخادم
يتيح JSON-RPC الوصول إلى جميع أساليب Python المحددة في نماذج Odoo:
# Confirm a sales order (triggers workflow)
call_kw("sale.order", "action_confirm", [[order_id]])
# Validate an inventory transfer
call_kw("stock.picking", "button_validate", [[picking_id]])
# Get the action for a button (useful for understanding what a button does)
action = call_kw("sale.order", "action_quotations_with_onboarding", [[]])
واجهة XML-RPC
XML-RPC هو واجهة برمجة تطبيقات Odoo الأصلية ويظل مدعومًا بالكامل. تتكون الواجهة من نقطتي نهاية:
/xmlrpc/2/common— الأساليب غير المصادقة (المصادقة، الإصدار)/xmlrpc/2/object— جميع عمليات النموذج (يتطلب UID)
import xmlrpc.client
url = "https://your-odoo.com"
db, username, password = "mydb", "admin", "mypassword"
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, username, password, {})
models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
# Search for products
product_ids = models.execute_kw(
db, uid, password,
'product.template', 'search',
[[['sale_ok', '=', True]]],
{'limit': 100}
)
# Read product data
products = models.execute_kw(
db, uid, password,
'product.template', 'read',
[product_ids],
{'fields': ['name', 'list_price', 'categ_id']}
)
# Create a new product
new_product_id = models.execute_kw(
db, uid, password,
'product.template', 'create',
[{
'name': 'My New Product',
'list_price': 99.99,
'type': 'consu'
}]
)
مرشحات المجال
يتم استخدام صيغة مرشح نطاق Odoo عبر جميع أنواع واجهات برمجة التطبيقات الثلاثة. يعد فهم المجالات أمرًا ضروريًا لاسترجاع البيانات بكفاءة.
# Basic operators: =, !=, >, <, >=, <=, like, ilike, in, not in, child_of
domain = [
["state", "in", ["sale", "done"]], # Confirmed or done orders
["amount_total", ">=", 1000], # Total at least 1000
["partner_id.country_id.code", "=", "US"] # US customers (related field)
]
# Logical operators: & (AND, default), | (OR), ! (NOT)
domain = [
"|",
["state", "=", "draft"],
["state", "=", "cancel"]
]
# Complex: orders from US or UK customers with total > 5000
domain = [
"|",
["partner_id.country_id.code", "=", "US"],
["partner_id.country_id.code", "=", "GB"],
["amount_total", ">", 5000]
]
خطافات الويب والتكامل القائم على الأحداث
يدعم Odoo 19 خطافات الويب الصادرة الناتجة عن تغييرات السجل. قم بتكوين خطافات الويب ضمن الإعدادات → التقنية → خطافات الويب.
تكوين خطاف الويب:
- انتقل إلى الإعدادات ← التقنية ← خطافات الويب ← إنشاء
- قم بتعيين النموذج (على سبيل المثال،
sale.order) - حدد المشغل: إنشاء أو كتابة أو إلغاء الارتباط أو طريقة مخصصة
- أدخل عنوان URL لنقطة النهاية لخدمة الاستقبال الخاصة بك
- قم باختيار النطاق لتصفية السجلات التي تقوم بتشغيل خطاف الويب
- قم بتكوين الحقول لتضمينها في الحمولة
تلقي أحداث webhook في خدمة Flask:
from flask import Flask, request, jsonify
import hmac, hashlib
app = Flask(__name__)
WEBHOOK_SECRET = "your_webhook_secret"
@app.route("/odoo-webhook", methods=["POST"])
def handle_webhook():
# Verify signature
signature = request.headers.get("X-Odoo-Signature")
body = request.get_data()
expected = hmac.new(
WEBHOOK_SECRET.encode(),
body,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
return jsonify({"error": "Invalid signature"}), 401
event = request.json
model = event.get("model")
record_id = event.get("id")
# Process the event
if model == "sale.order":
handle_order_event(record_id, event)
return jsonify({"status": "ok"}), 200
معالجة الأخطاء وإعادة المحاولة المنطقية
يجب أن تتعامل عمليات التكامل القوية مع أخطاء Odoo API بأمان.
import time
import requests
from requests.exceptions import RequestException
def api_call_with_retry(url, payload, headers, max_retries=3, backoff=2):
for attempt in range(max_retries):
try:
response = requests.post(url, json=payload, headers=headers, timeout=30)
response.raise_for_status()
data = response.json()
if "error" in data:
error = data["error"]
code = error.get("code", 0)
message = error.get("data", {}).get("message", "Unknown error")
# Don't retry validation errors
if code in [200, 100]:
raise ValueError(f"Odoo validation error: {message}")
raise RuntimeError(f"Odoo API error {code}: {message}")
return data.get("result")
except (RequestException, RuntimeError) as e:
if attempt == max_retries - 1:
raise
wait = backoff ** attempt
print(f"Attempt {attempt + 1} failed: {e}. Retrying in {wait}s...")
time.sleep(wait)
رموز الأخطاء الشائعة:
| الكود | معنى | العمل |
|---|---|---|
| 100 | خطأ في الخادم | تحقق من سجلات Odoo |
| 200 | تم رفض الوصول | التحقق من أذونات المستخدم |
| 300 | سجل مفقود | تحقق من وجود معرف السجل |
| 304 | الحقل المطلوب مفقود | مراجعة الحمولة |
أفضل ممارسات الأداء
العمليات المجمعة: لا تستدعي واجهة برمجة التطبيقات مطلقًا في حلقة للسجلات الفردية. استخدم create_multi وwrite مع القوائم:
# Bad: loop with individual creates
for product in products:
call_kw("product.template", "create", [product])
# Good: batch create
call_kw("product.template", "create", [products])
اختيار الحقل: حدد دائمًا المعلمة fields لتجنب جلب جميع الحقول:
# Good: only fetch needed fields
orders = call_kw(
"sale.order", "search_read",
[[["state", "=", "sale"]]],
{"fields": ["name", "amount_total"], "limit": 1000}
)
ترقيم الصفحات: بالنسبة لمجموعات البيانات الكبيرة، قم بترقيم الصفحات باستخدام limit وoffset:
def fetch_all_records(model, domain, fields, batch_size=500):
records = []
offset = 0
while True:
batch = call_kw(
model, "search_read", [domain],
{"fields": fields, "limit": batch_size, "offset": offset}
)
records.extend(batch)
if len(batch) < batch_size:
break
offset += batch_size
return records
الأسئلة المتداولة
ما الفرق بين JSON-RPC وREST API في Odoo 19؟
يوفر JSON-RPC إمكانية الوصول إلى واجهة برمجة تطبيقات Odoo Python الكاملة بما في ذلك جميع الطرق من جانب الخادم، بينما يتبع REST اصطلاحات OpenAPI 3.0 ويكشف عن واجهة أكثر محدودية ولكنها موحدة. بالنسبة لعمليات التكامل الجديدة حيث يغطي REST حالة الاستخدام الخاصة بك، يُفضل REST لقابليته للاكتشاف. لأتمتة سير العمل المعقدة أو الوصول إلى أساليب Python المخصصة، استخدم JSON-RPC.
كيف أتعامل مع عمليات تصدير البيانات الكبيرة (أكثر من 100 ألف سجل) بكفاءة؟
استخدم ترقيم الصفحات مع search_read وحجم دفعة يتراوح من 500 إلى 1000 سجل. بالنسبة للصادرات الكبيرة جدًا، فكر في استخدام ميزة التصدير الخاصة بـ Odoo عبر واجهة المستخدم لعمليات الاستخراج لمرة واحدة، أو جدولة مهام الخلفية باستخدام نموذج ir.cron الخاص بـ Odoo لمعالجة البيانات في أجزاء خارج ساعات الذروة بدلاً من إجراء مكالمات API في الوقت الفعلي.
هل يمكنني استخدام مفاتيح API بدلاً من اسم المستخدم/كلمة المرور لـ XML-RPC؟
نعم. في Odoo 13+، يمكن استخدام مفاتيح API ككلمات مرور في استدعاء مصادقة XML-RPC. قم بإنشاء مفتاح API من ملف تعريف المستخدم الخاص بك واستخدمه بدلاً من كلمة المرور الخاصة بك: common.authenticate(db, username, api_key, {}). هذا هو الأسلوب الموصى به لحسابات الخدمة.
كيف يمكنني إنشاء سجلات Many2many وOne2many عبر واجهة برمجة التطبيقات؟
استخدم مجموعات أوامر Odoo: (0, 0, vals) يقوم بإنشاء سجل جديد ذي صلة، (1, id, vals) يقوم بتحديث سجل مرتبط موجود، (2, id, 0) يحذف سجل مرتبط، (4, id, 0) يربط سجل موجود، (5, 0, 0) يلغي ربط جميع السجلات ذات الصلة. تعمل هذه الأوامر بشكل مماثل عبر JSON-RPC، وXML-RPC، وREST.
كيف يمكنني تشغيل إجراء سير العمل (مثل تأكيد الطلب) عبر واجهة برمجة التطبيقات؟
استدعاء الطريقة المقابلة في النموذج. لتأكيد أمر المبيعات، اتصل بـ action_confirm على sale.order. للتحقق من صحة التسليم، اتصل على button_validate على stock.picking. تظهر هذه الأساليب في كود مصدر Odoo ويمكن اكتشافها من خلال فحص سمة الزر name في وضع مطور واجهة المستخدم.
ما هي حدود الأسعار التي يفرضها Odoo على استدعاءات واجهة برمجة التطبيقات (API)؟
لا يفرض Odoo حدودًا لمعدلات واجهة برمجة التطبيقات (API) أصلاً على مستوى التطبيق. يجب تكوين تحديد المعدل على مستوى الوكيل العكسي (Nginx) أو البنية التحتية. الافتراضي المعقول هو 60 طلبًا في الدقيقة لكل عنوان IP لعمليات التكامل الخارجية. بالنسبة لعمليات التكامل عالية الإنتاجية، استخدم أسلوبًا قائمًا على قائمة الانتظار مع مستخدم خدمة مخصص.
الخطوات التالية
يتطلب إنشاء تكامل موثوق لـ Odoo API أكثر من مجرد أمثلة التعليمات البرمجية العاملة - فهو يتطلب معالجة مناسبة للأخطاء، والمراقبة، وإدارة بيانات الاعتماد، والمواءمة مع نموذج بيانات Odoo.
قام فريق التكامل في ECOSIRE ببناء اتصالات على مستوى الإنتاج بين Odoo وعشرات المنصات بما في ذلك Shopify وAmazon وGoHighLevel وPower BI وأنظمة تخطيط موارد المؤسسات (ERP) المخصصة والأنظمة الخاصة. نحن نتعامل مع بنية المصادقة وتصميم خطاف الويب وتحويل البيانات والمراقبة المستمرة.
تحدث إلى ECOSIRE حول مشروع تكامل Odoo الخاص بك →
سواء كنت تبدأ عملية تكامل جديدة أو تصلح عملية تكامل معطلة، فسيقوم مهندسونا بمراجعة متطلباتك وتقديم حل يتعامل مع الحالات المتطورة من اليوم الأول.
بقلم
ECOSIRE Research and Development Team
بناء منتجات رقمية بمستوى المؤسسات في ECOSIRE. مشاركة رؤى حول تكاملات Odoo وأتمتة التجارة الإلكترونية وحلول الأعمال المدعومة بالذكاء الاصطناعي.
مقالات ذات صلة
Odoo Accounting vs QuickBooks: Detailed Comparison 2026
In-depth 2026 comparison of Odoo Accounting vs QuickBooks covering features, pricing, integrations, scalability, and which platform fits your business needs.
AI + ERP Integration: How AI is Transforming Enterprise Resource Planning
Learn how AI is transforming ERP systems in 2026—from intelligent automation and predictive analytics to natural language interfaces and autonomous operations.
All-in-One vs Best-of-Breed: The Software Stack Decision
All-in-one vs best-of-breed software strategy for 2026: integration complexity, total cost, vendor risk, and when each approach is right for your business.