العمل مع S3 والتخزين السحابي في Rust: aws-sdk-s3
أصبحت مخازن الكائنات السحابية المتوافقة مع Amazon S3 المعيار الفعلي لتخزين الملفات والنسخ الاحتياطية والمحتوى الثابت والبيانات. في نظام Rust البيئي، يُستخدم AWS SDK الرسمي لـ Rust — aws-sdk-s3 — للعمل مع S3. تتيح هذه الأداة الاتصال ليس فقط بـ Amazon S3، بل وأيضًا بأي مخازن متوافقة مع S3: MinIO و Yandex Object Storage و DigitalOcean Spaces و Cloudflare R2 وغيرها.
التثبيت والإعداد
أضف التبعيات التالية إلى Cargo.toml:
[dependencies]aws-sdk-s3 = "1.15"aws-config = "1.1"tokio = { version = "1", features = ["full"] }anyhow = "1.0"للمصادقة، يمكنك استخدام متغيرات البيئة أو ملف تكوين AWS (~/.aws/credentials) أو تمرير المفاتيح برمجيًا. يبدو التهيئة الأدنى للعميل كالتالي:
use aws_sdk_s3::Client;use aws_config::meta::region::RegionProviderChain;
#[tokio::main]async fn main() -> Result<(), anyhow::Error> { let region_provider = RegionProviderChain::default_provider() .or_else("ru-central1"); let config = aws_config::from_env() .region(region_provider) .load() .await; let client = Client::new(&config); // ثم نعمل مع client Ok(())}العمليات الأساسية مع S3
إنشاء حاوية (Bucket)
use aws_sdk_s3::model::BucketLocationConstraint;
let bucket_name = "my-rust-bucket";let constraint = BucketLocationConstraint::from("ru-central1");let _ = client .create_bucket() .bucket(bucket_name) .create_bucket_configuration( aws_sdk_s3::model::CreateBucketConfiguration::builder() .location_constraint(constraint) .build() ) .send() .await?;رفع ملف (PutObject)
use aws_sdk_s3::primitives::ByteStream;use std::path::Path;
let file_path = "local_file.txt";let body = ByteStream::from_path(Path::new(file_path)).await?;
client .put_object() .bucket(bucket_name) .key("uploads/remote_file.txt") .body(body) .send() .await?;println!("تم رفع الملف");تنزيل ملف (GetObject)
use tokio::io::AsyncWriteExt;
let resp = client .get_object() .bucket(bucket_name) .key("uploads/remote_file.txt") .send() .await?;
let mut file = tokio::fs::File::create("downloaded.txt").await?;let mut stream = resp.body;while let Some(chunk) = stream.try_next().await? { file.write_all(&chunk).await?;}println!("تم تنزيل الملف");قائمة الكائنات في الحاوية
let objects = client .list_objects_v2() .bucket(bucket_name) .prefix("uploads/") .send() .await?;
for obj in objects.contents().unwrap_or_default() { println!("- {}", obj.key().unwrap_or("غير معروف"));}الاتصال بـ MinIO ومخازن أخرى متوافقة مع S3
للعمل مع MinIO (أو أي مخزن غير AWS)، يجب إعادة تعريف نقطة النهاية (endpoint) وتعطيل التحقق من توقيع المنطقة (إذا لزم الأمر). إليك مثال كامل:
use aws_sdk_s3::{Client, Config, Credentials, Region};use aws_smithy_client::erase::DynConnector;use aws_smithy_client::hyper_ext;use http::Uri;
let creds = Credentials::new( "minioadmin", "minioadmin", None, None, "minio",);
let endpoint = Uri::from_static("http://localhost:9000");let region = Region::new("us-east-1");
let config = Config::builder() .credentials_provider(creds) .region(region) .endpoint_resolver(endpoint) .force_path_style(true) // مهم لـ MinIO .build();
let client = Client::from_conf(config);// جميع العمليات مع client تتم الآن عبر MinIOيرجى ملاحظة