إنتقل إلى المحتوى الرئيسي

استدعاء خدمة خارجية من داخل برنامج نصي

الهدف​

أن تجعل برنامجًا نصيًا على الخادم يستدعي شيئًا خارج المنصة — يأخذ دفعة، أو يخبر نظامًا آخر بأن سجلًا قد تغيّر، أو يرسل بريدًا إلى شخص ما — وأن يكون العنوان الذي يُستدعى إعدادًا يتحكم فيه مسؤول، لا سطرًا في برنامجك النصي.

الدالتان​

كلتاهما متاحتان في خطوة إضافة الخادم وفي واجهة برمجية مخصّصة.

var answer = callService('par_payment_service', '{"reference":"ORD-1","amount":25}');

var sent = sendEmail('par_mail_service', { to: 'buyer@example.test', subject: 'Your order is paid', body: 'Thank you.' });

يمكن أن يكون الجسم نصًا، كما في الأعلى، أو كائنًا أو قائمة تُرسل بصيغة JSON: ‏callService('par_payment_service', { reference: 'ORD-1', amount: 25 }) يرسل الشيء نفسه.

تُجيب callService بكائن:

الخاصيةما هي
statusرمز حالة HTTP الذي ردّت به الخدمة
okتساوي true للحالات من ٢٠٠ إلى ٢٩٩، ليكون الحال الشائع خاصيةً واحدة لا عملية حسابية
bodyما ردّت به، كنص
truncatedتساوي true إذا كان الرد أكبر من أن يُقرأ كاملًا

الوسيط الأول اسم خدمة، لا عنوان​

هذا هو الجزء الذي يفاجئ الناس، وهو التصميم كلّه.

'par_payment_service' هو الاسم المنطقي لمتغيّر بيئة. أنت تعلنه في حلّك، ويحدّد مسؤول قيمته — أي نقطة النهاية — في كل بيئة. وعليه:

  • يقول برنامجك النصي ماذا يستدعي، ولا يقول أبدًا أين؛
  • تشير بيئة التطوير إلى بيئة اختبار وتشير بيئة الإنتاج إلى المزوّد الحقيقي، دون أي تغيير في الحل؛
  • والبيئة التي لم يُضبط لها شيء لا تصل إلى أي مكان.

لا توجد عمدًا أي دالة تأخذ عنوان URL. فدالة كهذه تتيح لأي برنامج نصي في أي مستأجر أن يفتح اتصالًا إلى أي مكان كان، ولا تعوّض عن ذلك أي مراجعة للحلول بعد وقوعه.

الإعداد​

١. أعلن الخدمة. في مركز التحكم الإداري، افتح متغيّرات البيئة وأنشئ واحدًا — par_payment_service من نوع نص. اكتب وصفًا يبيّن الغرض منه؛ فمن يضبطه في الإنتاج قد لا يكون أنت. ٢. أضفه إلى حلّك لكي يسافر معه. إعلان المتغيّر يسافر، أما قيمته فلا — وهذا ما يُبقي إعدادات التطوير بعيدة عن الإنتاج. ٣. اضبط القيمة في هذه البيئة — نقطة النهاية، وهي عنوان مطلق http:// أو https://. ٤. اكتب الخطوة. في خطوة الإضافة أو الواجهة المخصّصة، استدعِ callService بذلك الاسم.

من أي جانب من الحفظ تستدعي​

تعمل خطوة إضافة الخادم إما قبل كتابة السجل وإما بعدها، والاستدعاءات الخارجية تنتمي إلى جانبين مختلفين بحسب طبيعتها:

الاستدعاءالمرحلةلماذا
أخذ دفعة، أو حجز مخزون في نظام آخرPreOperationيقع داخل معاملة الحفظ، فإن فشل حفظ السجل بعده لا يبقى شيء يزعم أن مالًا قد أُخذ
إرسال تأكيد، أو إخطار نظام آخرPostOperationيكون السجل موجودًا عندئذ، فتعطّل خدمة البريد يؤخّر رسالة بدل أن يُلغي سجلًا

الاستدعاء قبل الحفظ يحصل على عشر ثوانٍ. فهو يُبقي الحفظ مفتوحًا في أثناء انتظاره، وشخص ما ينظر إلى مؤشّر انتظار. وإن كانت الخدمة التي تستدعيها تحتاج أطول من ذلك، فاجعل الخطوة غير متزامنة — عندها تعمل بعد الحفظ وحدها، وتأخذ ما تحتاجه من وقت.

ما الذي يُعدّ إخفاقًا​

يستحق هذا التمييز أن يُتعلّم مرة واحدة، لأنه يحدّد كم يلزمك أن تكتب من البرنامج النصي:

  • الحالة التي اختارتها الخدمة نفسها هي جواب. فـ 402 من بوابة دفع تعني أن البطاقة رُفضت — وهي نتيجة اعتيادية تقرّر أنت بشأنها. يحصل برنامجك عليها في answer.status ويمضي.
  • ألّا يأتي جواب البتة إخفاق، وهو يوقف الخطوة من تلقاء نفسه: لا توجد خدمة بهذا الاسم، أو لم تُضبط نقطة نهاية في هذه البيئة، أو نقطة النهاية ليست عنوان ويب، أو لم تردّ الخدمة قط. لا يستطيع البرنامج النصي فعل شيء حيال أيٍّ من ذلك، والمضيّ يعني التصرّف وكأن التكامل قد تمّ.

فتكون صورة أكثر الخطوات هكذا:

var answer = callService('par_payment_service', body);
if (answer.ok) {
setValue('par_payment_reference', answer.body);
} else {
throwValidationError(`The payment service refused this order (${answer.status}).`);
}

إرسال البريد​

تأخذ sendEmail اسم الخدمة ورسالة، وترسل الرسالة إلى تلك الخدمة. الرسالة مِلك المنصة، فيضبط النشر مُهايئ بريد واحدًا لا واحدًا لكل برنامج نصي يرسل رسالة.

في الرسالةما هو
toالمستلم. عنوان واحد، أو عدة عناوين تفصلها فواصل أو فواصل منقوطة، أو قائمة
ccمن يتلقى نسخة، بالطريقة نفسها. اختياري
replyToإلى أين يذهب الرد، ليجيب العميل من كتب لا عنوانًا لا يُرَد عليه. اختياري
subjectسطر الموضوع
bodyنص الرسالة
htmltrue إن كان النص HTML. اختياري؛ وإلا فنص عادي

لا توقف sendEmail برنامجك النصي أبدًا. جوابها { ok, error }. حين لا يُرسل البريد، لأن أحدًا لم يضبط خدمة بريد هنا، أو رُفض العنوان، أو كانت خدمة البريد متوقفة، يكون ok هو false ويقول error السبب، بكلمات تقول من يستطيع إصلاحه. هذا يتيح للبرنامج النصي تسجيل الإخفاق والمحاولة لاحقًا، وهكذا تعلّم مبيعات بارسوير البريد بأنه فشل. وإن كان ينبغي أن يتوقف الحفظ بدلًا من ذلك، فقل ذلك:

if (!sent.ok) { throwValidationError(sent.error); }

البرنامج النصي المكتوب قبل ذلك كان يمرّر أربعة وسائط (sendEmail(service, to, subject, body))، ويجب أن ينتقل إلى صيغة الرسالة أعلاه.

المنصة لا تتحدث SMTP. إنها ترسل إلى ما تسمّيه البيئة، وهو ما يوفّره كل مزوّد بريد؛ أما النشر الذي سبيله الوحيد مُرحِّل SMTP فيضع أمامه نقطة نهاية HTTP صغيرة.

جرّبه​

استورد الحل النموذجي business-rules-outbound-calls. فيه جدول طلبات، وخدمتان معلنتان كمتغيّرات بيئة دون ضبط أي قيمة، وخطوتان — واحدة تأخذ الدفعة قبل الحفظ وأخرى ترسل التأكيد بعده. ويشرح ملف README خطوةً خطوة كيف توجّه الخدمتين إلى نقطة تردّ بـ 200 ثم إلى نقطة تردّ بـ 402، وترى الحفظ يُرفض دون أن يُخزَّن شيء.

انظر أيضًا​