Slonik؛ کلاینت پستگرس با تایپ سختگیر
خلاصهٔ کاملتر
تو این مقاله که در واقع مستندات خودِ پروژهست، Slonik بهعنوان یه کلاینت PostgreSQL برای Node.js معرفی میشه که زیر کاپوتش از درایور node-postgres استفاده میکنه ولی یه لایهٔ امنیت و راحتی روش گذاشته. فلسفهش اینه که تو رو به نوشتن SQL خام تشویق کنه و از ساختِ پویا و سرهمبندیشدهٔ کوئری دلسرد کنه؛ یعنی برخلاف ORMها، خود SQL رو مینویسی ولی با ابزارهای امن.
یکی از انگیزههای اصلی ساختش، حذف کدهای تکراری و اضافهکردن تایپسیفتی بوده. به گفتهٔ نویسنده، وقتی متدهای کمکی نداری، برای یه کوئری ساده مجبوری دستی چک کنی که چند ردیف برگشته و برای هر حالت خطا بندازی. متد oneFirst همهٔ این منطق رو تو خودش جمع میکنه:
const getFooIdByBar = (
connection: DatabaseConnection,
bar: string,
): Promise<DatabaseRecordIdType> => {
return connection.oneFirst(sql.typeAlias("id")`
SELECT id
FROM foo
WHERE bar = ${bar}
`);
};همین oneFirst اگه کوئری هیچ ردیفی برنگردونه NotFoundError میندازه، و اگه چند ردیف یا چند ستون برگردونه DataIntegrityError. نویسنده میگه فایدهش اینه که خطا دقیقاً سرِ منبع مشکل بهت اشاره میکنه، نه اینکه یه نتیجهٔ غیرمنتظره بیسروصدا بره تو عملیات بعدی و باعث باگهای سختپیداشدن یا حتی خرابی داده بشه. در ضمن چون شکل خروجی تضمینشدهست، بعضی خطاها رو تایپچکِ استاتیک قبل از اجرا میگیره.
بخش بعدی دربارهٔ مدیریت امنِ کانکشنه. Slonik فقط اجازه میده یه کانکشن رو در طول همون تابع پرامیسی که به pool.connect() میدی استفاده کنی. دلیلش اینه که اگه خودت دستی کانکشن بگیری و کوئری ارور بده، ممکنه release() صدا زده نشه و کانکشن تا ابد باز بمونه. این الگو تضمین میکنه بهمحض اینکه کار تموم یا رد شد، کانکشن آزاد میشه. تراکنشها هم همینطورن: فقط داخل تابع transaction() معتبرن و اگه با کانکشنی که مال تراکنش نیست کوئری بزنی، خطای UnexpectedForeignConnectionError میگیری.
شاید مهمترین بخش امنیتی، محافظت در برابر تزریق ناامن مقادیر (SQL injection) باشه. نویسنده توضیح میده که راه درست، پارامتریکردنه: متن کوئری و مقدار ورودی جدا به سرور فرستاده میشن تا پستگرس خودش امن جایگذاری کنه. آسیبپذیری وقتی پیش میاد که کسی بهجای پارامتر، ورودی کاربر رو مستقیم با رشتهٔ کوئری بههم بچسبونه. Slonik با تَگ تمپلیت sql کاری میکنه که مقادیر همیشه بهصورت پارامتر بایند بشن، نه اینکه خام وارد متن کوئری بشن.
نکات کلیدی:
- Slonik یه کلاینت PostgreSQL روی node-postgres هست که SQL خام رو تشویق میکنه ولی امن و تایپدار.
- متدهایی مثل one، many و oneFirst کد تکراری چککردن نتیجه رو حذف میکنن و خطای دقیق میندازن.
- کانکشن فقط داخل تابع pool.connect() و تراکنش فقط داخل transaction() معتبره تا چیزی لو نره.
- تَگ تمپلیت sql مقادیر رو بهصورت پارامتر بایند میکنه و جلوی SQL injection رو میگیره.
- بعد از آزادشدن کانکشن، بهصورت پیشفرض DISCARD ALL اجرا میشه تا state بین کوئریها لو نره.




