Skip to main content
تُعدّ node-postgres (الحزمة pg) أكثر مشغّلات Postgres استخدامًا في Node.js. في هذا الدليل، ستتصل بخدمة ClickHouse Managed Postgres عبر pg.Pool مع تحقق كامل من شهادة TLS، ثم تُنشئ جدولين، وتُحوّل الأموال بين الحسابات ضمن معاملة واحدة، وأخيرًا تعرض البيانات عبر خادم node:http صغير.

المتطلبات الأساسية

  • Node.js الإصدار 20.6 أو أحدث (للاستفادة من العلامة المدمجة --env-file). اختُبر هذا الدليل باستخدام Node.js 24.21.0 وpg 8.23.1.
  • حساب على ClickHouse Cloud
  • psql، لإنشاء قاعدة البيانات

إنشاء خدمة ClickHouse Managed Postgres

في وحدة تحكم ClickHouse Cloud، انقر على New service ثم اختر Postgres. سيصبح المثيل جاهزًا في غضون دقائق معدودة. للاطلاع على شرح تفصيلي للخطوات، راجع دليل البدء السريع.

الحصول على بيانات الاتصال

انقر على Connect في الشريط الجانبي الأيسر لخدمتك. بعد تحديد Directly، انسخ URL الاتصال من علامة التبويب url. اترك Use SSL معطّلاً، إذ يمرّر التطبيق شهادة CA ضمن الشيفرة بدلاً من تضمينها في URL (راجع تهيئة مجمّع الاتصالات). يتصل هذا الدليل مباشرةً بـ Postgres على المنفذ 5432. فخادم Node.js الذي يعمل لفترات طويلة يحتفظ أصلاً بمجمّع اتصالات خاص به عبر pg.Pool، لذا لا حاجة إلى أداة تجميع اتصالات ثانية أمام Postgres. أما إذا كنت تشغّل عمليات كثيرة أو دوالاً بلا خادم، فاستخدم PgBouncer المضمّن بدلاً من ذلك؛ راجع استخدام PgBouncer. بعد ذلك، نزّل شهادة CA الخاصة بمثيلك. فعّل Use SSL وانقر على Download CA certificate، أو انتقل إلى Settings → CA Certificate → Download CA certificate. هذه الشهادة خاصة بمثيلك وحده.

إعداد المشروع

أنشئ مشروعًا وثبّت pg:
هل تُضيف ذلك إلى تطبيق قائم؟تخطَّ الأمرين mkdir وnpm init -y. شغّل npm install pg داخل مشروعك، ثم انتقل إلى إنشاء قاعدة البيانات.
الأمثلة الواردة في هذا الدليل مكتوبة كوحدات ES بالامتداد .mjs، ولذلك تعمل سواء كان ملف package.json في مشروعك يستخدم CommonJS أو وحدات ES.

إنشاء قاعدة البيانات

انقل ملف <service-name>-ca-certificate.pem الذي نزّلته إلى دليل المشروع، وأعِد تسميته إلى ca-certificate.pem، ثم أنشئ قاعدة بيانات للتطبيق:
أنشئ ملف .env يتضمن URL الاتصال الذي نسخته بعد تغيير اسم قاعدة البيانات فيه إلى guide_nodejs، إضافةً إلى مسار الشهادة:
.env
إذا كانت كلمة المرور تحتوي على محارف مثل @ أو / أو #، فاستخدم ترميز النسبة المئوية (percent-encoding) لترميزها في عنوان URL.

تهيئة مجمّع الاتصالات

أنشئ الملف db.mjs. يُصدِّر هذا الملف مجمّع اتصالات واحدًا تتشاركه بقية أجزاء التطبيق:
db.mjs
يمنحك تمرير ssl: { ca } ما يعادل sslmode=verify-full: إذ تتحقق pg من أن شهادة الخادم موقَّعة من CA الخاص بالمثيل لديك، ومن أنها تطابق اسم المضيف. القيمة الافتراضية لـ rejectUnauthorized هي true؛ فلا تضبطها على false.
لا تجمع بين ssl ومعلمات SSL في عنوان URLإذا احتوى DATABASE_URL على sslmode أو sslrootcert، فإن pg تبني إعدادات TLS انطلاقًا من عنوان URL وتتجاهل الكائن ssl. فعلى سبيل المثال، إذا انتهى عنوان URL بـ ?sslmode=verify-full دون sslrootcert، فإنه يحل محل ca الخاص بك، ويفشل الاتصال بالخطأ unable to verify the first certificate. لذا لا تضع معلمات SSL في DATABASE_URL عند تمرير ssl في الشيفرة.لاحظ أيضًا ما يلي:
  • إذا لم يوجد الكائن ssl ولا sslmode في عنوان URL، فإن pg لا تستخدم TLS ولا تتحقق من الخادم.
  • تقرأ pg المتغيرات PGHOST وPGUSER وPGPASSWORD وما شابهها، لكنها لا تقرأ PGSSLROOTCERT. ولذلك فإن المتغيرات الموجودة في علامة التبويب env ضمن نافذة Connect لا تكفي وحدها للتحقق من الخادم.
  • إذا كنت تفضّل إبقاء كل شيء في عنوان URL، فإن عنوان URL الذي تعرضه نافذة Connect عند تفعيل Use SSL يعمل أيضًا مع pg، مثل ...?sslmode=verify-full&sslrootcert=ca-certificate.pem. وفي هذه الحالة، احذف الخيار ssl، ولاحظ أن مسار sslrootcert يُحدَّد نسبةً إلى الدليل الذي تشغّل منه Node.js.

إنشاء المخطط

أنشئ الملف setup.mjs. يتولى هذا الملف إنشاء الجداول، وإدراج حسابين باستخدام استعلامات ذات معلمات، ثم قراءتهما للتحقق منهما:
setup.mjs
مرِّر القيم دائمًا كمعلمات ($1، $2، …) بدلًا من دمجها في string الخاص باستعلام SQL. إذ يرسلها pg منفصلةً عن نص الاستعلام، ما يحول دون هجمات حقن SQL. كما تُحوَّل مصفوفات JavaScript إلى مصفوفات Postgres، كما هو الحال في الاستعلام ANY($1). شغِّله:
تُعيد مكتبة pg قيم numeric (وbigint) على هيئة سلاسل نصية (strings) تجنّبًا لفقدان الدقة. لذا، حوّلها صراحةً إذا كنت تحتاج إليها كأرقام.

تنفيذ الاستعلامات ضمن معاملة

يجب أن تُنفَّذ المعاملة على اتصال واحد، لذا احجز عميلًا من مجمّع الاتصالات باستخدام pool.connect، واحرص دائمًا على تحريره بعد الانتهاء. أنشئ الملف transfer.mjs:
transfer.mjs
لا تستخدم pool.query لتنفيذ العبارات داخل المعاملة، إذ قد يُنفَّذ كل استدعاء لـ pool.query على اتصال مختلف.

تقديم البيانات عبر HTTP

أنشئ الملف server.mjs. يقدّم هذا الملف الحسابات وعمليات التحويل بتنسيق JSON على المنفذ 3107، ويستقبل عمليات تحويل جديدة، ويتوقف بشكل سليم عند تلقّي الإشارة SIGINT (Ctrl+C) أو SIGTERM:
server.mjs
استدعِ pool.end مرة واحدة فقط عند إيقاف العملية، لا بعد كل طلب؛ إذ ينتظر حتى تُعاد جميع العملاء المستعارة إلى مجمّع الاتصالات، ثم يغلق كل الاتصالات.

التحقق

شغّل الخادم:
في طرفية ثانية، نفّذ عملية تحويل، ثم جرّب تحويلًا يتجاوز رصيد الحساب، وآخر إلى حساب غير موجود:
كانت عملية النقل الثالثة قد خصمت المبلغ من حساب alice بالفعل عند فشلها، غير أن ROLLBACK ألغى هذا الخصم. افتح http://localhost:3107/accounts في متصفحك لعرض الأرصدة. ستبدو الاستجابة على النحو التالي:
للتأكد من أن الاتصال يستخدم TLS مع التحقق من الشهادة، نفّذ استعلامًا على pg_stat_ssl:
إذا وجّهت DATABASE_CA_CERT إلى أي شهادة أخرى، يفشل الاتصال ويظهر الخطأ unable to verify the first certificate، ما يؤكد أن شهادة الخادم يجري التحقق منها فعلاً. أخيراً، أوقف الخادم بالضغط على Ctrl+C. ستظهر الرسالة SIGINT received, shutting down تليها Pool closed. يمكنك أيضاً استعراض البيانات في وحدة التحكم. افتح SQL console، ثم وسّع قاعدة البيانات guide_nodejs، وافتح الجدول accounts:

استخدام PgBouncer

للاتصال عبر PgBouncer المضمَّن، اختر via PgBouncer في نافذة Connect واستخدم المنفذ 6432 في DATABASE_URL. لا حاجة إلى أي تغييرات في الشيفرة، فشهادة CA نفسها تعمل كما هي. يعمل PgBouncer في وضع تجميع المعاملات (transaction pooling)، ما يعني أن كل معاملة قد تُنفَّذ على اتصال Postgres مختلف. عند استخدام pg:
  • تعمل الاستعلامات ذات المعلمات، والعبارات المُعدّة المسمّاة (pool.query({ name, text, values }))، والمعاملات التي تستخدم pool.connect كما هو موضّح في هذا الدليل.
  • لا تنتقل عبارتا PREPARE وEXECUTE على مستوى SQL، ولا إعدادات الجلسة المضبوطة باستخدام SET، من معاملة إلى أخرى. استخدم SET LOCAL داخل المعاملة بدلاً من ذلك.
  • يعرض pg_stat_ssl معلومات الاتصال بين PgBouncer وPostgres، ولذلك يُرجع استعلام التحقق من TLS الوارد أعلاه القيمة ssl: false. ومع ذلك، يظل اتصال تطبيقك بـ PgBouncer خاضعاً للتحقق، إذ يفشل الاتصال بالطريقة نفسها عند استخدام شهادة CA خاطئة.

الخطوات التالية