العمل مع S3 والتخزين السحابي في TypeScript
تستخدم تطبيقات الويب الحديثة بشكل متزايد التخزين الكائني السحابي لتخزين الملفات والصور والنسخ الاحتياطية والمحتوى الثابت. يُعد Amazon S3 (Simple Storage Service) المعيار الفعلي في هذا المجال، وتدعم واجهة برمجة التطبيقات الخاصة به معظم مزودي الخدمات السحابية والحلول المحلية مثل MinIO و DigitalOcean Spaces أو Yandex Object Storage. في هذه المقالة، سننظر في كيفية العمل مع التخزين المتوافق مع S3 في TypeScript باستخدام AWS SDK الرسمي والمكتبات البديلة.
اختيار مكتبة للعمل مع S3 في TypeScript
للتفاعل مع S3 من TypeScript، توجد عدة حلول شائعة:
- @aws-sdk/client-s3 — SDK الرسمي من Amazon، مكتوب بلغة TypeScript، معياري وحديث.
- aws-sdk — الإصدار الكلاسيكي من SDK (v2)، والذي لا يزال مدعومًا، لكن يُنصح بالانتقال إلى الإصدار v3.
- minio — مكتبة عميل لـ MinIO وأي تخزين متوافق مع S3، بسيطة وخفيفة.
- s3-client — غلاف بسيط حول fetch API للعمل مع S3.
سنركز على @aws-sdk/client-s3 باعتباره الأداة الأكثر حداثة وقوة، وسنعرض أيضًا أمثلة باستخدام minio للحالات التي تحتاج فيها إلى بديل خفيف.
التثبيت والإعداد
قم بتثبيت الحزم اللازمة عبر npm:
npm install @aws-sdk/client-s3 @aws-sdk/lib-storagenpm install --save-dev @types/node typescriptللعمل مع MinIO:
npm install minioالآن لننشئ عميل S3 أساسي. تأكد من وجود متغيرات بيئة أو إعدادات تحتوي على مفاتيح الوصول.
مثال 1: تهيئة عميل S3
import { S3Client } from "@aws-sdk/client-s3";
const s3Client = new S3Client({ region: process.env.AWS_REGION || "us-east-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID!, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!, }, // بالنسبة لـ MinIO أو S3 المحلي، حدد endpoint: // endpoint: "http://localhost:9000", // forcePathStyle: true,});
export default s3Client;لاحظ المعامل forcePathStyle — وهو إلزامي لـ MinIO وبعض التخزينات غير التابعة لـ AWS.
مثال 2: رفع ملف إلى S3
لرفع ملف، نستخدم الأمر PutObjectCommand:
import { PutObjectCommand } from "@aws-sdk/client-s3";import s3Client from "./s3Client";
async function uploadFile(bucket: string, key: string, body: Buffer | string) { const command = new PutObjectCommand({ Bucket: bucket, Key: key, Body: body, ContentType: "application/octet-stream", });
try { const response = await s3Client.send(command); console.log("تم رفع الملف:", response.$metadata.httpStatusCode); return response; } catch (error) { console.error("خطأ في الرفع:", error); throw error; }}
// الاستخدام:await uploadFile("my-bucket", "uploads/image.png", bufferFromFile);لرفع الملفات الكبيرة بشكل تدفقي، استخدم @aws-sdk/lib-storage:
import { Upload } from "@aws-sdk/lib-storage";import { Readable } from "stream";
const upload = new Upload({ client: s3Client, params: { Bucket: "my-bucket", Key: "large-file.zip", Body: Readable.from(fileStream), },});
upload.on("httpUploadProgress", (progress) => { console.log(`تم الرفع: ${progress.loaded} من ${progress.total}`);});
await upload.done();مثال 3: تنزيل ملف
لاسترجاع كائن من التخزين، نستخدم GetObjectCommand:
أيضاً في المكتبة
توصيات