مساحة تخزين عالية الأداء لتطبيقك: واجهة برمجة التطبيقات Storage Foundation

يقدم نظام الويب الأساسي بشكل متزايد للمطوّرين الأدوات التي يحتاجونها لإنشاء تطبيقات عالية الأداء ومتطورة للويب. ومن الجدير بالذكر أنّ WebAssembly (Wasm) فتح المجال أمام تطبيقات الويب السريعة والفعّالة، في حين أنّ تكنولوجيات مثل Emscripten تتيح الآن لمطوّري البرامج إعادة استخدام الرموز البرمجية التي تم اختبارها واختبارها على الويب. للاستفادة من هذه الإمكانات حقًا، يجب أن يتمتع المطورون بنفس القوة والمرونة عندما يتعلق الأمر بالتخزين.

هنا يأتي دور واجهة برمجة تطبيقات Storage Foundation. Storage Foundation API هي واجهة برمجة تطبيقات جديدة وسريعة للتخزين تتيح لك الاستفادة من حالات استخدام جديدة مطلوبة كثيرًا على الويب، مثل تنفيذ قواعد بيانات عالية الأداء وإدارة الملفات المؤقتة الكبيرة بسلاسة. باستخدام هذه الواجهة الجديدة، يمكن لمطوّري البرامج "توفير مساحة التخزين الخاصة بهم" على الويب، ما يقلّل من الفجوة في الميزات بين رمز الويب والنظام الأساسي.

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

لماذا يحتاج الويب إلى واجهة برمجة تطبيقات أخرى لمساحة التخزين؟

تقدم منصة الويب عددًا من خيارات التخزين للمطورين، ولكل منها حالات استخدام محددة في الاعتبار.

  • من الواضح أنّ بعض هذه الخيارات لا تتداخل مع هذا الاقتراح لأنّها تسمح فقط بتخزين كميات صغيرة جدًا من البيانات، مثل ملفات تعريف الارتباط أو Web Storage API التي تتكوّن من الآليتين sessionStorage وlocalStorage.
  • ويتم إيقاف الخيارات الأخرى نهائيًا لأسباب مختلفة مثل واجهة برمجة تطبيقات إدخالات الملفات والدليل أو WebSQL.
  • تحتوي File System Access API على واجهة برمجة تطبيقات مشابهة، غير أنّ استخدامها يهدف إلى التفاعل مع نظام الملفات لدى العميل وتوفير إمكانية الوصول إلى البيانات التي قد تكون خارجة عن النطاق المصدر أو حتى ملكية المتصفّح. يأتي هذا التركيز المختلف مع اعتبارات أمان أكثر صرامة وتكاليف أداء أعلى.
  • يمكن استخدام IndexedDB API كخلفية لبعض حالات استخدام Storage Foundation API. على سبيل المثال، يتضمن Emscripten IDBFS، وهو نظام ملفات دائم مستند إلى IndexedDB. مع ذلك، بما أنّ أداة IndexedDB هي في الأساس مخزن لقيم المفاتيح، فإنها تفرض قيودًا كبيرة على الأداء. بالإضافة إلى ذلك، يصبح الوصول المباشر إلى الأقسام الفرعية من الملف أكثر صعوبة وأبطأ ضمن أداة IndexedDB.
  • وأخيرًا، تتوافق واجهة التخزين المؤقت على نطاق واسع، ويتم ضبطها لتخزين البيانات الكبيرة الحجم، مثل موارد تطبيقات الويب، ولكن القيم غير قابلة للتغيير.

تهدف واجهة Storage Foundation API إلى سد جميع الثغرات في خيارات التخزين السابقة من خلال السماح بالتخزين المؤقت للملفات الكبيرة القابلة للتغيير والمحددة داخل مصدر التطبيق.

حالات الاستخدام المقترَحة لواجهة Storage Foundation API

تتضمّن أمثلة المواقع الإلكترونية التي قد تستخدم واجهة برمجة التطبيقات هذه ما يلي:

  • تطبيقات الإنتاجية أو الإبداع التي تعمل على كميات كبيرة من بيانات الفيديو أو الصوت أو الصور ويمكن لهذه التطبيقات نقل الأجزاء إلى القرص بدلاً من الاحتفاظ بها في الذاكرة.
  • هي التطبيقات التي تعتمد على نظام ملفات دائم يمكن الوصول إليه من خلال Wasm وتحتاج إلى أداء أكبر مما يمكن أن يضمنه IDBFS.

ما هي واجهة برمجة تطبيقات Storage Foundation؟

هناك جزءان رئيسيان في واجهة برمجة التطبيقات:

  • استدعاءات نظام الملفات، التي توفر الوظائف الأساسية للتفاعل مع الملفات ومسارات الملفات
  • مؤشرات الملفات: توفّر إمكانية الوصول للقراءة والكتابة إلى ملف حالي.

طلبات نظام الملفات

تقدِّم واجهة Storage Foundation API عنصرًا جديدًا، storageFoundation، يتوفّر في الكائن window ويتضمن عددًا من الدوال:

  • storageFoundation.open(name): يؤدي النقر إلى فتح الملف بالاسم الذي تم تحديده إذا كان متوفرًا، وإنشاء ملف جديد بخلاف ذلك. عرض وعد يتم حله مع الملف المفتوح.
  • storageFoundation.delete(name): يؤدي هذا الإجراء إلى إزالة الملف الذي يحمل الاسم المحدّد. يعرض وعدًا بحله عند حذف الملف.
  • storageFoundation.rename(oldName, newName): لإعادة تسمية الملف من الاسم القديم إلى الاسم الجديد بشكل كامل. عرض وعد يتم حله عند إعادة تسمية الملف.
  • storageFoundation.getAll(): تعرض وعدًا يتم حله مع مصفوفة من جميع أسماء الملفات الحالية.
  • storageFoundation.requestCapacity(requestedCapacity): يطلب سعة جديدة (بالبايت) للاستخدام وفقًا لسياق التنفيذ الحالي. يعرض وعدًا يتم حله مع توفر الكمية المتبقية من السعة.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity): يطلق عدد محدد من وحدات البايت من سياق التنفيذ الحالي، ويعرض وعدًا تتم ملاءمته مع السعة المتبقية.
  • storageFoundation.getRemainingCapacity(): تعرض وعدًا تتماشى مع السعة المتاحة لسياق التنفيذ الحالي.

مؤشرات الملفات

يتم التعامل مع الملفات من خلال الدوال التالية:

  • NativeIOFile.close(): يُغلق ملفًا ويعرض وعدًا يتم حله عند اكتمال العملية.
  • NativeIOFile.flush(): لمزامنة (أي مسح) حالة ذاكرة الملف مع جهاز التخزين، وعرض وعود يتم تنفيذه عند اكتمال العملية.
  • NativeIOFile.getLength(): يعرض وعدًا يتم حله مع طول الملف بالبايت.
  • NativeIOFile.setLength(length): لضبط طول الملف بالبايت، وعرض وعد يحل عند اكتمال العملية. إذا كان الطول الجديد أصغر من الطول الحالي، تتم إزالة وحدات البايت بدءًا من نهاية الملف. وإلا يتم تمديد الملف بوحدات بايت ذات قيمة صفرية.
  • NativeIOFile.read(buffer, offset): يقرأ محتوى الملف حسب الإزاحة المحدّدة من خلال مخزن مؤقت ناتج عن نقل المخزن المؤقت المحدد، والذي يتم تركه منفصلاً. تعرض NativeIOReadResult مع المخزن المؤقت المنقول وعدد وحدات البايت التي تمت قراءتها بنجاح.

    NativeIOReadResult هو كائن يتألف من إدخالَين:

    • buffer: ArrayBufferView، وهي نتيجة نقل المورد الاحتياطي الذي تم تمريره إلى read(). من نفس نوع وطول المخزن المؤقت المصدر.
    • readBytes: عدد وحدات البايت التي تمت قراءتها بنجاح في buffer. قد يكون هذا أقل من حجم المخزن المؤقت، في حالة حدوث خطأ أو إذا كان نطاق القراءة يمتد إلى ما بعد نهاية الملف. ويتم ضبطه على صفر إذا كان نطاق القراءة يقع بعد نهاية الملف.
  • NativeIOFile.write(buffer, offset): يكتب محتوى المخزن المؤقت المحدد في الملف بالمعادلة المحددة. يتم نقل المخزن المؤقت قبل كتابة أي بيانات وبالتالي يتم تركه منفصلاً. تعرض NativeIOWriteResult تتضمن المخزن المؤقت المنقول وعدد وحدات البايت التي تمت كتابتها بنجاح. سيتم تمديد الملف إذا تجاوز نطاق الكتابة طوله.

    NativeIOWriteResult هو كائن يتألف من إدخالَين:

    • buffer: ArrayBufferView وهي نتيجة نقل المورد الاحتياطي الذي تم تمريره إلى write(). من نفس نوع وطول المخزن المؤقت المصدر.
    • writtenBytes: عدد وحدات البايت التي تمت كتابتها بنجاح في buffer. قد يكون هذا أقل من حجم المخزن المؤقت في حالة حدوث خطأ.

أمثلة كاملة

لجعل المفاهيم التي تم تقديمها أعلاه أكثر وضوحًا، إليك مثالين كاملين يرشدانك خلال المراحل المختلفة في دورة حياة ملفات Storage Foundation.

الفتح والكتابة والقراءة والإغلاق

// Open a file (creating it if needed).
const file = await storageFoundation.open('test_file');
try {
  // Request 100 bytes of capacity for this context.
  await storageFoundation.requestCapacity(100);

  const writeBuffer = new Uint8Array([64, 65, 66]);
  // Write the buffer at offset 0. After this operation, `result.buffer`
  // contains the transferred buffer and `result.writtenBytes` is 3,
  // the number of bytes written. `writeBuffer` is left detached.
  let result = await file.write(writeBuffer, 0);

  const readBuffer = new Uint8Array(3);
  // Read at offset 1. `result.buffer` contains the transferred buffer,
  // `result.readBytes` is 2, the number of bytes read. `readBuffer` is left
  // detached.
  result = await file.read(readBuffer, 1);
  // `Uint8Array(3) [65, 66, 0]`
  console.log(result.buffer);
} finally {
  file.close();
}

جارٍ الفتح وبطاقة بيانات المتجر والحذف

// Open three different files (creating them if needed).
await storageFoundation.open('sunrise');
await storageFoundation.open('noon');
await storageFoundation.open('sunset');
// List all existing files.
// `["sunset", "sunrise", "noon"]`
await storageFoundation.getAll();
// Delete one of the three files.
await storageFoundation.delete('noon');
// List all remaining existing files.
// `["sunrise", "noon"]`
await storageFoundation.getAll();

عرض توضيحي

يمكنك تشغيل العرض التوضيحي لواجهة برمجة التطبيقات Storage Foundation API في المحتوى المضمّن أدناه. قم بإنشاء الملفات وإعادة تسميتها والكتابة فيها وقراءتها من الملفات، ومعرفة السعة المتاحة التي طلبتها التحديث أثناء إجراء التغييرات. يمكنك العثور على رمز المصدر للعرض التوضيحي على تطبيق Glitch.

الأمان والأذونات

صمَّم فريق Chromium ونفّذها باستخدام المبادئ الأساسية الموضّحة في التحكّم في الوصول إلى ميزات النظام الأساسي الفعّال للويب، بما في ذلك إمكانية التحكّم في المستخدم والشفافية وتسهيل الاستخدام.

إنّ الوصول إلى واجهة برمجة التطبيقات Storage Foundation API على الويب يتّبع النمط نفسه المتّبع في واجهات برمجة تطبيقات التخزين الحديثة الأخرى، ما يعني أنّ المصدر قد لا يصل إلا إلى البيانات المنشأة ذاتيًا. كما أنها تقتصر على السياقات الآمنة.

تحكم المستخدم

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

روابط مفيدة

شكر وتقدير

تم تحديد تطبيق Storage Foundation API وتنفيذه من قِبل Emanuel Krivoy وريتشارد ستوتز. تمت مراجعة هذه المقالة من قِبل بيت ليبيج وجو ميدلي.

صورة رئيسية من قناة Markus Spiske على Un التصميم