ساخت یک SDK برای API ویدیو با امنیت نوع (Type-Safe) در Rust

فساد داده‌ها (Data corruption) اغلب بی‌صدا رخ می‌دهد.

در فصل گذشته، بک‌اند من متادیتای ویدیو را از هشت منطقه دریافت می‌کرد. سیستم قدیمی از یک اسکریپت PHP استفاده می‌کرد. این سیستم تا زمانی که یک ارائه‌دهنده فیلدی را تغییر نداد، به خوبی کار می‌کرد. یک برچسب زمانی (timestamp) بدشکل باعث شد اسکریپت ردیف‌های بیهوده (garbage rows) را در پایگاه داده ما بنویسد.

ما تا سه روز متوجه این موضوع نشدیم. سیستم از کار نیفتاد؛ فقط عناوین خالی را به کاربران نشان می‌داد.

من لایه دریافت داده (fetch layer) را با یک Rust SDK جایگزین کردم. من Rust را انتخاب کردم چون reqwest و serde یک قرارداد داده‌ای (data contract) سخت‌گیرانه را اعمال می‌کنند. اگر داده‌ها اشتباه باشند، سیستم در همان مرز (boundary) با خطا مواجه می‌شود و آن را به وضوح اعلام می‌کند. در این صورت، داده‌های غلط در پایگاه داده نوشته نمی‌شوند.

روش ساخت آن به این صورت بود:

تعریف قرارداد داده (Data Contract) من از serde استفاده کردم تا دقیقاً مشخص کنم یک ویدیو چه ساختاری دارد. برای فیلدهایی که ممکن است وجود نداشته باشند، از Option استفاده کردم. همچنین برای مدیریت فرمت‌های مختلف تاریخ، از یک deserializer سفارشی برای timestamps استفاده کردم. این کار از خطای رایج "1970-01-01" در سیستم‌های قدیمی جلوگیری می‌کند.

دسته‌بندی خطاها یک SDK خوب به شما می‌گوید که چرا یک درخواست با شکست مواجه شده است. من از thiserror برای ایجاد یک لیست خطای مشخص استفاده کردم. خطاهای گذرا (transient errors) مانند محدودیت نرخ درخواست (rate limits) را از خطاهای بحرانی (fatal errors) مانند عدم دسترسی مجاز (unauthorized access) جدا کردم. این کار به سیستم اجازه می‌دهد تا به جای هدر دادن منابع، تصمیمات هوشمندانه‌ای برای تلاش مجدد (retry) بگیرد.

مدیریت اتصالات من از reqwest::Client برای حفظ یک استخر اتصال (connection pool) استفاده کردم. این کار از بار اضافی (overhead) ناشی از شروع دست‌دادن‌های (handshakes) جدید TLS برای هر درخواست جلوگیری می‌کند.

ساده‌سازی منطق با استفاده از Streamها من از async_stream برای مدیریت صفحه‌بندی (pagination) استفاده کردم. فراخواننده (caller) نیازی به مدیریت توکن‌های صفحه ندارد؛ آن‌ها صرفاً روی یک جریان (stream) از ویدیوها پیمایش (iterate) می‌کنند.

نتیجه، سیستمی است که از پایگاه داده محافظت می‌کند. وب‌سایت اصلی همچنان با PHP اجرا می‌شود. پایگاه داده همچنان SQLite است، اما اکنون تضمین می‌شود که داده‌های ورودی به پایگاه داده، تمیز و سالم هستند.

برای رسیدن به امنیت نوع (type safety)، نیازی به بازنویسی کل اپلیکیشن خود ندارید. فقط کافی است فرآیند اعتبارسنجی (validation) را به نقطه‌ای منتقل کنید که داده‌ها وارد سیستم شما می‌شوند.

منبع: https://dev.to/ahmet_gedik778845/building-a-type-safe-video-api-sdk-in-rust-with-reqwest-and-serde-41bf