AWS S3 ve DynamoDB ile Banner Servisi

Şimdi auth servisinden sonra banner servisine geçiyoruz. O yüzden yeni bir servis oluşturacağız.

 

Öncelikle burada banner görseli upload edeceğimiz için S3 hakkında konuşacağız.

S3 nedir?

AWS S3 (Amazon Simple Storage Service) AWS’in sunduğu dosya depolama servisidir. Dünyadaki en popüler bulut depolama hizmetlerinden biridir ve internette gördüğün birçok büyük uygulama (Instagram, Netflix, Airbnb vb.) S3 kullanır. S3; uygulamalarının ihtiyaç duyduğu tüm dosyaları saklamak için kullanılır. S3’te depolanan bu dosyalara internetten URL ile erişilebilir.

Şimdi serverless.yml dosyamı yazdım ve sls deploy komutuyla servisimi deploy ediyorum.

 

 

 

En başta oluşturduğumuz bucketname eklenmiş oldu. Serverless yml dosyamda dikkat ederseniz enviroment değişkenimi de tanımladım.

 

 

Handlers klasörü oluşturup içerisine uploadBanner fonksiyonumu yazdım bunun içerisinde s3 işlemlerimi yazacağım.

 

 

Bu kod ile S3’e dosya yüklemek için “presigned upload URL” üretiyoruz. Frontend (React, mobil app vb.) bu URL’yi alır ve S3’e doğrudan dosya yükleyebilir. Dosya backend üzerinden geçmez direkt “S3 → AWS Storage” içine gider. S3 tarafından imzalanmış, 3600 saniye (1 saat) geçerli özel bir link oluşturulur.

 

 

Bu şekilde uploadBanner fonksiyonumuza karşılık gelecek route’u da tanımladık. Şimdi sls deploy diyerek deployu gerçekleştiriyoruz.

 

 

 

İlgili route’a yükleyeceğimiz dosyanın adını ve type değerini yazıyoruz ve karşılığında yükleme url’i alıyoruz. Sonrasında bu url’i kopyalayıp bir PUT isteği gerçekleştireceğiz.

 

 

Binary seçeneği ile dosyamızı gönderiyoruz. Ama bir erişim hatası aldık. Yani lambda’ya s3 nesne iznini vermemiz gerekiyor.

 

 

 

S3 Bucketımızdan ARN bilgisini alıp serverless.yml da iamRolestatemanets tanımını yapıyoruz. Burada izin verdiğimiz aksiyon ‘s3:PutObject’ oluyor. Resource ekinin sonuna ‘/*’ işaretini eklemeyi unutmayın. Şimdi tekrar deneyelim.

 

 

 

200 OK bilgisini aldık.

 

 

 

 

Ama erişemiyoruz. S3 varsayılan olarak genel erişimi engelliyor. Bunun için genel erişimi etkinleştireceğiz.

 

 

Tüm herkese açık erişimi engelleyin seçeneği açık görünüyor şimdi bunu düzenleyelim.

 

 

 

Sonrasında bucket politikasını düzenleyelim.

 

 

Bu şekilde politikayı ekleyip kaydetmemiz yeterli. Unutmayın resource sizin bucket arn isminiz olacak. Principal": "*" herkese açık olduğunu söyler. s3:GetObject ise bu bucket içindeki dosyaların okunması / indirilmesi için izin verir. Recource arn sonundaki /* eki bucket içindeki tüm dosyaları kapsar.

 

 

İşlem başarılı. Şimdi DynamoDB entegrasyonunu yapalım.

 

 

 

banners tabolumuzu serverless.yml dosyamızda tanımladık. String türünde fileName bilgisini tutacak. Aynı zamanda environment içerisinde Banners tablomun adını tutacak bir key tanımladım. Şimdi dosya url’ini dynamoDb’e yüklemek için yeni bir lambda fonksiyonu yazacağım. Bu fonksiyon diğer fonksiyonlarımızdan farklı olarak bir S3 Event Trigger olacak.

 

 

Bu fonksiyon S3’e dosya yüklendikten sonra otomatik çalışan bir Lambda fonksiyonudur. Yapacağı iş yüklenen dosyanın bilgilerini DynamoDB’ye kaydetmek. Yani S3 Upload Trigger Lambda olarak çalışacak. Adımlarımız sırasıyla bu şekilde:

Kullanıcı dosya yüklemek için presigned URL aldı.

Bu URL’ye dosyayı S3’e yükledi.

Yükleme işlemi bittiğinde S3 otomatik olarak bu Lambda’yı tetikledi.

Böylece React uygulaması veya başka servisler yüklenen dosyaların listesini DynamoDB’den okuyabilir.

 

 

confirmUpload fonksiyonumu serverless.yml dosyamda yazdım. Bu yapı, S3’e bir dosya yüklendiğinde Lambda fonksiyonunu otomatik çalıştırmak için gerekli Serverless ayarıdır. Events altında dikkat edersek httpApi değil s3 yazıyor yani bir s3 olayıyla tetiklenecek bir fonksiyon yazdık. existing: true ile bucket zaten varsa yeni bir bucket yazma diyoruz.

 

 

Şimdi lambdaya öğeyi dynamodb’e yazma izni vereceğiz.

 

 

Resource bilgisini dynomodb de Banners tablosundan alabiliriz.

 

 

Şimdi deneyelim.

 

 

uploadUrl’i kopyalayıp PUT isteği ile dosyayı gönderelim.

 

 

DynamoDB banner tablosuna gidip explore table items butonuna basarak datamızı görebiliriz.

 

 

 

 

Ve bu işlemimizde başarılı. Şimdi 2 adet mikroservisimiz var birisi AuthService diğeri de BannerService şeklinde.

Bu arada burada bahseceğim database vs table per service yaklaşımları var. Örneğin mikroservislerde her bir servis farklı veritabanlarını da kullanabilir örneğin authService postgresql kullanırken bannerService mongodb olabilirdi. Yani her hizmetin kendi veritabanı olabilirdi. Ancak bizim kullandığımız yaklaşım Table per service yaklaşımıdır. Tüm hizmetler bir veritabanını paylaşıyor ancak her birinin kendine ayrı bir alanı var.