العمل مع S3 والتخزين السحابي في JavaScript (Node.js)
\n\nS3 (Simple Storage Service) هو المعيار الفعلي للتخزين الكائني في السحابة. بغض النظر عما إذا كنت تستخدم Amazon S3 أو Yandex Object Storage أو Mail.ru Cloud Storage أو حلًا محليًا مثل MinIO، تظل واجهة API موحدة. في هذه المقالة، سنشرح كيفية الاتصال بمخازن S3 المتوافقة من Node.js باستخدام AWS SDK v3 الرسمي.
\n\nما هو S3 ولماذا هو مطلوب؟
\nيتيح S3 تخزين عدد غير محدود من الملفات (الكائنات) في "سلال" (buckets). كل كائن له مفتاح فريد (مسار) وبيانات وصفية. حالات الاستخدام الرئيسية:
\n- \n
- تخزين ملفات المستخدمين (الصور الرمزية، المستندات) \n
- النسخ الاحتياطي لقواعد البيانات والسجلات \n
- الملفات الثابتة لتطبيقات الويب (الصور، CSS، JS) \n
- تخزين ملفات الوسائط (فيديو، صوت) \n
تثبيت وإعداد AWS SDK v3
\nبدءًا من الإصدار 3، أصبح AWS SDK معياريًا. للعمل مع S3، يكفي تثبيت حزمة واحدة:
\nnpm install @aws-sdk/client-s3\n\nستحتاج أيضًا إلى متغيرات بيئة تحتوي على مفاتيح الوصول. من الأفضل تخزينها في ملف .env:
AWS_ACCESS_KEY_ID=your_access_key\nAWS_SECRET_ACCESS_KEY=your_secret_key\nAWS_REGION=ru-central1\nS3_ENDPOINT=https://storage.yandexcloud.net\nS3_BUCKET=my-bucket\n\nالاتصال بمخزن S3 متوافق
\nلنقم بإنشاء عميل S3 مع نقطة نهاية مخصصة (لـ Yandex Object Storage و MinIO وغيرها):
\nconst { S3Client } = require('@aws-sdk/client-s3');\nrequire('dotenv').config();\n\nconst s3Client = new S3Client({\n region: process.env.AWS_REGION,\n endpoint: process.env.S3_ENDPOINT,\n credentials: {\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n },\n forcePathStyle: true, // مهم لـ MinIO وبعض مخازن S3 المتوافقة\n});\n\nmodule.exports = s3Client;\n\nالعمليات الأساسية مع S3
\n\n1. رفع ملف (PutObject)
\nنقوم برفع ملف من مخزن مؤقت أو تدفق:
\nconst { PutObjectCommand } = require('@aws-sdk/client-s3');\nconst fs = require('fs');\n\nasync function uploadFile(filePath, key) {\n const fileContent = fs.readFileSync(filePath);\n \n const command = new PutObjectCommand({\n Bucket: process.env.S3_BUCKET,\n Key: key,\n Body: fileContent,\n ContentType: 'image/png', // حدد نوع MIME الصحيح\n });\n\n try {\n const response = await s3Client.send(command);\n console.log('تم رفع الملف:', response.$metadata.httpStatusCode);\n return `https://storage.yandexcloud.net/${process.env.S3_BUCKET}/${key}`;\n } catch (err) {\n console.error('خطأ في الرفع:', err);\n }\n}\n\n2. تنزيل ملف (GetObject)
\nنحصل على الكائن ونحفظه محليًا:
\nconst { GetObjectCommand } = require('@aws-sdk/client-s3');\nconst fs = require('fs');\nconst stream = require('stream');\nconst { promisify } = require('util');\nconst pipeline = promisify(stream.pipeline);\n\nasync function downloadFile(key, destinationPath) {\n const command = new GetObjectCommand({\n Bucket: process.env.S3_BUCKET,\n Key: key,\n });\n\n try {\n const response = await s3Client.send(command);\n const writeStream = fs.createWriteStream(destinationPath);\n await pipeline(response.Body, writeStream);\n console.log('تم تنزيل الملف:', destinationPath);\n } catch (err) {\n console.error('خطأ في التنزيل:', err);\n }\n}\n\n3. الحصول على قائمة الكائنات (ListObjectsV2)
\nمفيد لعرض الملفات في السلة:
\nconst { ListObjectsV2Command } = require('@aws-sdk/client-s3');\n\nasync function listFiles(prefix = '') {\n const command = new ListObjectsV2Command({\n Bucket: process.env.S3_BUCKET,\n Prefix: prefix,\n MaxKeys: 100,\n });\n\n try {\n const response = await s3