Singleton Desing Pattern

Singleton patterni ile bir nesnenin çalışma zamanında tek olmasını garanti edebiliriz. Böyle söyleyince kafamızda bir şeyler canlanmadıysa daha somut örnekler veriyim. Örneğin;

  • veritabanı kullandığımız uygulamalarımızda connectionString bilgisini okumak için kullanabiliriz.
  • Projemizdeki konfigürasyon bilgilerini okumak için de kullanabiliriz.

 

İmplementasyonu çok basit. Aşağıdaki UML şemamızı inceleyerek işe başlayalım.

  • Singleton isimli bir class oluşturduk.
  • Bu class’ın constructorını private olarak tanımlıyoruz. Bunun sebebi ise herkes Singleton singleton=new Singleton() şeklinde belleğe yeni bir nesne yaratmasını engellemek.
  • Yine private olarak Singleton tipinde bir _instance yaratıyoruz.
  • Bu nesneye ulaşmak için ReturnInstance tipinde public bir metot yazıyoruz.
Bu şekilde classımız yazmış olduk. Ama asenkron işlemlerde kullanmak istersek bu metodumuzu thread safe hale getirmeliyiz. Bunu da lock koyarak halledebiliriz.
 

 

.NET Core ve Redis Kullanarak Distributed Cache Mekanizması Kurma

Redis Nedir?

Redis özünde key-value tipinde NoSQL bir veritabanıdır.  En önemli artısı ise verileri bellekte tutmasıdır. Çoğunuzun aklına bizim çok datamız var bu kadar belleği nereden bulacağız gibi sorular gelebilir. String-string tipinde datalar tutuyorsak 1M adet data 100 mb gibi bir yer kaplıyor.

Öncelikle Redis’i yükleyelim;

  • Komut satırını yönetici olarak çalıştırıp aşağıdaki kodu çalıştıralım.
  • Chocolatey yüklendikten sonra şimdi de Redis’i yükleyelim
  • Komut satırına “redis-server” yazdığımızda aşağıdaki gibi bir ekranla karşılaşmamız lazım.

Şimdi bir tane .NET Core Web API oluşturalım. Bu örnek projede database first olarak ilerleyeceğim. Hedefim ise öğrenci bilgilerini bu öğrencinin aldığı dersleri tutmak üzerine olacak. Basitçe aşağıdaki veritabanını tasarladım.

Şimdi API endpointlerimizi oluşturalım ve cache olmadan bir benchmark çalıştıralım. Sonuçlarımıza bakalım.

ID’si girilen öğrencinin adını soyadını ve aldığı dersleri bize dönen endpointimiz yazdık.

Şimdi “ab – Apache HTTP sunucusu başarım ölçme aracı” ile sunucumuza yük bindirelim.

Şimdi projemize Redis Cache ekleyelim.

  • Nuget üzerinden “Microsoft.Extensions.Caching.Redis.Core” paketini yükleyelim.
  • Controllerimize aşağıdaki değişkeni global olarak ekleyelim.
Controllerimizde gerekli değişikleri yapalım.
Benchmark sonuçlarımıza göz atalım.

 

Kaynak kod: https://github.com/limanerkan/RedisTutorial

 

Computer Vision APİ Kullanımı

Selamlar,

Önceki yazımda RESTful api tasarlama ilkelerinden bahsetmiştim. Bu yazımda ise bu ilkeleri kullanarak bir api geliştireceğiz. Microsoft’un fotoğraf analizleri için geliştirdiği ve azure platformu üzerinde bizlere sunduğu Computer Vision API’sini kullanacağız. Projemizde kullanacağımız ekipmanlar ise şöyle;

  • .NET Core 1.1 Web API
  • Swagger
  • Azure Blob
  • Azure Computer Vision API

Projemiz API üzerinden bize post edilen imajı Azure Blob’a atacak. Bu esnada bu imaj Vision API aracılığıyla işlenecek ve taglenecek. Sonrasında biz bu imajları kategorilerine göre sınıflandırabileceğiz ya da tagler üzerinden arama yapabileceğiz.

Hadi başlayalım.

Öncelikler .NET Core Web API projesi oluşturalım. Daha sonra projemize RESTful apiler için dokümantasyon aracı olan Swagger’i kuralım.

Packege Manage Console’a aşağıdaki komutu verelim

Sonrasında Startup.cs içerisindeki gerekli yerlere eklemeleri yapalım.

Swagger aracını yüklemiş olduk. http://localhost:portNo/swagger/ adresine gittiğimizde aşağıdaki gibi bir ekranla karşılaşmamız lazım.

Şimdi ImageController isminde bir conroller oluşuralım. Sadece get ve post metotları olsun.

Swagger eklentimizde. Fotoğraflarımızı upload etmek için ufak birkaç değişiklik yapmamız gerekiyor ki aşağıdaki gibi dosyayı seçebilelim.

FileOperation isimli bir class oluşturalım. Startup.cs içinde aşağıdaki değişikleri yapalım.

Swagger aracındaki gerekli ayarlamaları yaptıktan sonra azure üzerinde blob yaratalım.

New>Storage>Storage Account

Sonrasında ise Blob Service içinde profileimages isminde bir container yaratalım. Aynı şekilde bir tane de computer vision api oluşturalım.

New>AI+Cognitive Services>Computer Vision API

Şimdi kodlarımızı yazmaya başlayabiliriz.

Blob container içine resmi upload edecek ve resmi çağırınca getirecek bir class yazalım.

NOT: Azure üzerinde blob oluşturduğumuzda blob ismini, konteyner ismini ve keyimizi bir yere not edelim ve aşağıdaki classta gerekli yerlere yazalım.

 

Yukarıdaki classta yükleyeceğimiz resmin ismini benzersiz yapmalıyız. Aksi taktirde aynı isimle resim yüklenirse çakışma olabilir bunu için FileNameHelper isimli bir class yazdım. Basitçe bir guid oluşturuyor.

Şimdi ise vision api ile yüklenen resmin taglemek için gerekli işlemleri yapan classımızı yazalım.

Son olarak endpointlerimizde yukarıda yazdığımız classları çağıralım.

 

Aşağıdaki resmi upload edelim ve taglarine bakalım.

Sonuçlarımıza bakalım.

Caption değerimiz : a young boy sitting at a table with a plate of food with broccoli

Categories: people_young  ve fotoğrafra 20’ye yakın tag oluşturdu şimdi ise bu taglerden birisi ile arama yapalım. Bakalım API miz bize bu fotoğrafın bilgilerini geri dönecek mi?

Projeyi buradan indirebilirisiniz

https://github.com/limanerkan/AzureBlobAndVisionApi

RESTful API Tasarlama – Best Practices

Facebook, Google, Amazon, Github gibi pek çok teknoloji devi geliştiricilere ürünlerini ve verilerini API’ler aracılığıyla kullanma şansı veriyor.  Biz de kendi projelerimizi geliştirirken bu API’leri kullanıyoruz. Ya da kendi projelerimizde API endpointlerimiz oluyor. Kısa bir giriş yaptıktan sonra esas meselemize gelelim. Nedir bu RESTful APİ?

1)REST(Representional State Transfer)

Basitçe client-server arasındaki haberleşmeyi sağlayan mimaridir. REST mimarisini kullanan servislere RESTful servis denir. Belki bir çoğunuzun aklına zaten bu veri alış-verişini sağlayan SOAP gibi mimariler mevcut neden SOAP vb. mimariler yerine REST’i tercih etmeliyim gibi sorular gelmiş olabilir. SOAP gibi mimariler günümüzde çok kompleks kalıyor. REST ise HTTP protokolü üzerinden çalışan bir mimaridir. RESTful servisler ile çok farklı şekillerde response alabiliriz. Popüler olarak JSON kullanılsa da XML, CSV gibi türlerde de response alınabilir.

2) API endpointleri

Kendi projemde yazdığım bir endpointten örnek vermek istiyorum. Kullanıcı ile ilgili işlemleri yaptığımız bir endpoint var peki bunu nasıl tasarlamalıyım?

  • /addUser
  • /updateUser
  • /deleteUser
  • /showUser
  • /showAllUser

Yukarıda verdiğim örnekte kullanıcısı datası üzerinde işlem yapmak için bir sürü endpoint açmam gerekti. API sayısı arttıkça işler daha da karmaşık hale gelecekti. Bu çok efektif bir yaklaşım değil. Peki bu kullanıcı endpointini nasıl yaratmalıyım?

  • URL, sadece ve sadece isimleri içermelidir. Yukarıdaki add, update, delete, show gibi kelimeler olmamalı /Users

Tamam, URL ve ismi hallettik. Peki biz bu API’ye işlemleri nasıl yaptıracağız. İşte tam bu noktada HTTP metotları(GET, POST, DELETE, PUT) rol oynuyor.

  • metot GET /Users => tüm kullanıcıları getirir
  • metot GET /Users/1 => id’si 1 olan kullanıcıyı getir
  • metot DELETE /Users/1 => id’si 1 olan kullanıcıyi sil

Bu aşamaya kadar yazıyı okumaya devam ettiyseniz artık daha tutarlı(consistent) APİ’ler yazmaya başlayabilirsiniz.

Özet: pathlerimiz sadece ve sadece isimlerden oluşmalıdır. HTTP metotları ile bu isimler üzerinde gerçekleştirilecek eylem türleri kullanılmalıdır.

3. HTTP Metotları ve Durum Kodları

4 temel metodumuz var.

METOT AMACI
POST CREATE
GET READ
PUT UPDATE
DELETE DELETE

 

Durum kodlarımız ise;

  • 1XX ile başlayan kodlar bilgi amaçlı kodlardır.
  • 2XX ile başlayan kodlar başarı kodlarıdır.
  • 3XX ile başlayan kodlar yönlendirme kodlarıdır.
  • 4XX ile başlayan kodlar ise client(istemci) hatası kodlarıdır.
  • 5XX ile başlayan kodlar ise server(sunucu) hatası kodlarıdır.

4) Arama, sıralama, filtreleme ve sayfalama

  • Sıralama Eğer client kullanıcı bilgilerini yaşa göre sıralı bir şekilde almak isterse, GET /Users endpointine bir sıralama parametresi eklemeliyiz. GET /Users?sort=age_asc gibi…
  • Filtreleme Eğer client kullanıcı bilgilerini ülke veya dil bazında filtrelemek isterse şu tip bir yapı kurulabilir. GET /Users?location=turkey
  • Arama Eğer client kullanıcı bilgilerinde id’ye göre değil de direk isme göre arama yapmak isterse şu tip bir yapı kurulabilir. GET /Users?searcName=erkan liman
  • Sayfalama(pagination) client tarafında özellikle mobil cihazlarda tüm kullanıcı datasını ya da iki kullanıcının mesajlaşmalarını tek bir seferde getirmeye çalışırsak memory muhtemelen yetmeyecektir. Bu yüzden dataları sayfalamamız gerekir. GET /User?page=10

5) API Versiyonlama

Production ortamındaki bir endpointinize yeni özellikler kattığınızda ya da bazı özellikleri kapattığınızda bunun client tarafında güncellenmesi epey zaman alabilir ya da hiç güncellenmeyebilir. Bu yüzden direk production’da endpointi etkilememiz lazım. Bunun en efektif yolu ise versiyonlamadır. Eğer ben www.apidemo.com/Users şeklinde bir tasarım yaptıysam bu direk client tarafında patlamama sebep olur. www.apidemo.com/v1/Users şeklinde bir tasarım yapmalıyım. Yeni özellikleri ise www.apidemo.com/v2/Users şeklinde çıkmalıyım.

Bağlı Liste(Linked List) Yapısı

Programlama dillerinde birden çok veriyi tutmak için genellikle dizileri kullanırız. Ancak dizileri kullanmak için verimizin boyutunu bilmemiz gerekir. Eğer bilmiyorsak ya da belirlediğimiz değerin üzerine çıkmak istiyorsak sıkıntı yaşarız. Yaşayacağımız bir diğer sıkıntı ise elimizdeki veri setinin arasına bir değer girmek istersek ortaya çıkar. Örneğin 500 elemanlı bir dizinin 300. elemanına dışarıdan başka bir değer girersek 300. elemandan sonraki değerleri birer kaydırmamız gerekir. İşte tüm bunları aşmak için bağlı liste(linked list) kullanabiliriz.

Bağlantılı liste kullanmanın avantaj ve dezavantajları;

  • Dinamik boyuta sahip oluruz
  • Araya eleman eklerken fazla maliyet oluşturmaz

 

  • Rastgele erişim yoktur
  • Pointer için fazladan alan kullanırız.

 

Linked list temel işlemlerimiz

  • Ekle
  • Sil
  • Ara
  • Bul
  • Yok et

  • Her bir elemanımıza düğüm(node) denir.
  • Bağlanmış düğümler serisine bağlantılı liste denir.
  • Her düğümde veri ve işaretçi bulunur.
  • Baş; ilk düğüme olan işaretçidir.
  • Son düğüm NULL işaret eder.

Şimdi implemente edelim

Öncelikle 2 ana sınıfımız olacak. Bunlar Node ve List

Şimdi de InsertNode fonksiyonumuzu yazalım. Kabaca algoritması;

  • index’inci elemanı bul
  • Yeni düğüm için hafızada yer ayır
  • Yeni düğüm kendisinden sonrasını gösterecek
  • Yeni düğümden önceki düğüm yeni düğümü gösterecek

Yukarıdaki işlemleri yaparken 2 farklı durumla karşılaşırız.

  • İlk düğüm olarak ekleme
  • Ortaya ve sona ekleme
FindNode fonskiyonumuz

  • Listede x verisini ara
  • Böyle bir düğüm varsa pozisyonunu dön yoksa 0 dön
DeleteNode fonksiyonu

  • Silinecek düğümü bul
  • Bulunan düğümü hafızadan sil
  • Düğümden önceki pointer düğümden sonraki pointeri göstersin.

Ekleme işleminde olduğu gibi 2 özel durumumuz var.

  • İlk düğümü silme
  • Ortadaki veya sonraki düğümü silme
Listedeki elemanları ve eleman sayısını yazdırma
Listeyi silme
 

Örnek işlemler

Projeyi buradan indirebilirsiniz