~/zafer
Tüm yazılara dön
2 dk okuma

MinIO Üzerine İnce Bir S3 İstemcisi Sarmalamak

MinIO, S3 protokolüyle uyumlu bir self-hosted object storage. Bu da resmi AWS SDK'sını (@aws-sdk/client-s3) MinIO'ya karşı da kullanabileceğin anlamına geliyor — ama üç ayarı doğru yapman şartıyla.

// apps/api/src/storage/storage.service.ts
this.client = new S3Client({
  endpoint: `${protocol}://${hostAndPort}`,
  region: 'us-east-1',
  forcePathStyle: true,
  credentials: {
    accessKeyId: this.config.getOrThrow<string>('MINIO_ACCESS_KEY'),
    secretAccessKey: this.config.getOrThrow<string>('MINIO_SECRET_KEY'),
  },
});

forcePathStyle: true — en kritik satır

AWS S3, varsayılan olarak "virtual-hosted style" URL kullanır (bucket.s3.amazonaws.com). Self-hosted MinIO'da bucket adına göre otomatik subdomain oluşturacak bir DNS/wildcard-certificate altyapısı yok — bu yüzden forcePathStyle: true ile SDK'ya "path style" kullan diyoruz (minio-host/bucket/key). Bu satır unutulursa istekler yanlış bir hostname'e gitmeye çalışır ve sessizce başarısız olur.

region: 'us-east-1' — anlamsız ama zorunlu bir değer

MinIO'nun gerçek bir "AWS region" kavramı yok, ama SDK region parametresi olmadan çalışmayı reddediyor. us-east-1 burada sadece SDK'nın imzalama (signing) algoritmasını tatmin eden bir placeholder — MinIO bu değeri hiç kullanmıyor.

Endpoint'i ortam değişkenlerinden inşa etmek

const host = this.config.getOrThrow<string>('MINIO_ENDPOINT');
const port = this.config.get<string>('MINIO_PORT');
const useSsl = this.config.get<string>('MINIO_USE_SSL') === 'true';
const protocol = useSsl ? 'https' : 'http';
const hostAndPort = port ? `${host}:${port}` : host;

MINIO_PORT bilinçli olarak opsiyonel: yerel geliştirmede MinIO'ya doğrudan bir portla bağlanılıyor, prod'da ise reverse proxy 443/80 arkasında port belirtmeye gerek kalmıyor — aynı kod, iki farklı deployment şeklini env değişkenleriyle karşılıyor.

Servis neden upload/get'ten fazlasını bilmiyor

StorageService sadece iki metod sunuyor: upload(key, body, contentType) ve get(key). Presigned URL üretme, multipart upload, bucket policy yönetimi gibi S3'ün geri kalan yüzeyi bilinçli olarak dışarıda bırakılıyor — bu API'nin gerçek ihtiyacı bu ikisi, SDK'nın tüm yüzeyini sarmalamak (wrap) gereksiz bir soyutlama olurdu.