<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mustafa Emre Başar</title>
    <description>The latest articles on DEV Community by Mustafa Emre Başar (@emrebasar).</description>
    <link>https://dev.to/emrebasar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F688177%2F6ef71c28-3add-4031-8d08-0d6deb5b9c31.png</url>
      <title>DEV Community: Mustafa Emre Başar</title>
      <link>https://dev.to/emrebasar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emrebasar"/>
    <language>en</language>
    <item>
      <title>Resilience4j</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Sun, 14 Aug 2022 11:16:00 +0000</pubDate>
      <link>https://dev.to/emrebasar/resilience4j-2b9l</link>
      <guid>https://dev.to/emrebasar/resilience4j-2b9l</guid>
      <description>&lt;p&gt;Resilience4j, birbirleri ile iletişim içerisinde bulunan sistemler için hata toleransını yöneterek daha esnek bir yapı içerisinde&lt;br&gt;
işlemlerinı sürdürmelerine yardımcı olan bir kütüphanedir. Bir noktadaki hatanın bütün sistemi etkilememesi asıl amaçtır.&lt;/p&gt;

&lt;p&gt;Gerçekleştirmesinde Decorator Pattern ve Fonksiyonel Programlama konseptlerinden faydalanır.&lt;/p&gt;

&lt;p&gt;Bu esnek yapıyı oluşturmak için çeşitli temel parçalar içerir; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CircuitBreaker&lt;/li&gt;
&lt;li&gt;Retry&lt;/li&gt;
&lt;li&gt;TimeLimiter&lt;/li&gt;
&lt;li&gt;RateLimiter&lt;/li&gt;
&lt;li&gt;Bulkhead&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Circuit Breaker
&lt;/h2&gt;

&lt;p&gt;Sistemdeki hata veya gecikmenin belirlenebilen bir eşik değerinin üzerine çıktığı durumlarda, kaynakların boşa harcanmaması için bağlantının kesilmesi olayıdır.&lt;/p&gt;

&lt;p&gt;Bu oranı gözlemlemek için &lt;em&gt;&lt;strong&gt;sliding window&lt;/strong&gt;&lt;/em&gt; kullanılır ve iki tipi vardır;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Count Based&lt;/strong&gt; : Son N çağrı göz önünde bulundurulur ve çıktılarını N boyutunda bir circular array içerisinde toplar. Bu çağrılarda gecikme veya hata oranı eşik değeri aşarsa, devre kesilir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time Based&lt;/strong&gt; : Son N saniyede gelen çağrıların çıktıları için N boyutunda bir circular array oluşturur. Her bir indeks bir saniyelik aralığa denk gelmektedir. Her bir indekste  &lt;strong&gt;hatalı&lt;/strong&gt;, &lt;strong&gt;gecikmeli&lt;/strong&gt; ve &lt;strong&gt;toplam&lt;/strong&gt; çağrıları belirten 3 ayrı integer tutulur. Bu değerlerin oranına göre devrenin kesilmesine karar verilir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tanımlanan listelere veri girişi olduğu zaman yapılan hesaplama ile belirlenen hata ve gecikme eşik değerleri karşılaştırılır ve durum değişiklikleri yapılır.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;failureRateThreshold&lt;/strong&gt; : Hata oranının eşik değeridir, varsayılan olarak %50 durumundadır.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;slowCallRateThreshold&lt;/strong&gt; : Gecikme oranının eşik değeridir, varsayılan olarak %100 durumundadır. Bir çağrının gecikme olarak kabul edilmesi de (slow call) &lt;strong&gt;&lt;em&gt;slowCallDurationThreshold&lt;/em&gt;&lt;/strong&gt; değerine bağlıdır. Varsayılan olarak 60000 ms üzeri süren bir çağrı gecikme olarak kabul edilir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bu eşik değerleri ile ilgili bir diğer önemli bir nokta da, kontrole dahil edilmeleri, toplam istek sayısının &lt;strong&gt;&lt;em&gt;minimumNumberOfCalls&lt;/em&gt;&lt;/strong&gt; değerini aşmasından sonra gerçekleşir. Örneğin bu değer 10 olduğunda, gelen 9 istek de hatalı olsa dahi &lt;strong&gt;&lt;em&gt;minimumNumberOfCalls&lt;/em&gt;&lt;/strong&gt; değeri henüz aşılmadığı için devre kesilmez.&lt;/p&gt;

&lt;h3&gt;
  
  
  Devre Durumları
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SuHXBpj---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omz81vtcavs3bpgzvjva.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SuHXBpj---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omz81vtcavs3bpgzvjva.jpg" alt="circuitbreakerstates" width="426" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Devrenin bulunabileceği 3 farklı durum söz konusudur;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CLOSED&lt;/strong&gt; : Devre kesiminin gerçekleşmediği, her şeyin normal seyrinde devam ettiği durumdur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OPEN&lt;/strong&gt; : Hata veya gecikme oranlarının eşik değerleri aşıldığında sistemin bulunduğu durumdur. Bu durumda iken gelen istekler &lt;strong&gt;&lt;em&gt;CallNotPermittedException&lt;/em&gt;&lt;/strong&gt; hatası ile geri çevrilir. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HALF-OPEN&lt;/strong&gt; : Kesilmiş bir devrenin, &lt;strong&gt;&lt;em&gt;waitDurationInOpenState&lt;/em&gt;&lt;/strong&gt; ile belirlenen süreyi beklemesinden sonra, direk olarak &lt;strong&gt;CLOSED&lt;/strong&gt; durumuna geçmek yerinde geçtiği ara durumdur. Bu durumda 
&lt;strong&gt;&lt;em&gt;permittedNumberOfCallsInHalfOpenState&lt;/em&gt;&lt;/strong&gt; ile belirtilen miktarda istek alınmasına izin verilir. Eğer bu isteklerdeki hata veya gecikme oranı eşik değerlerinden yüksek ise tekrar &lt;strong&gt;OPEN&lt;/strong&gt; durumuna, değil ise &lt;strong&gt;CLOSED&lt;/strong&gt; durumuna geçilir. Bu duruma geçişin otomatik bir şekilde yapılması için &lt;strong&gt;&lt;em&gt;automaticTransitionFromOpenToHalfOpenEnabled&lt;/em&gt;&lt;/strong&gt; değerinin &lt;strong&gt;true&lt;/strong&gt; olarak ayarlanması gereklidir.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Bu işlemeler dahilinde varsayılan olarak, bütün Exception tipleri hata olarak sayılır. Ancak bu yaklaşım yerine kendi ayarlamalarımızı da yapabiliriz;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;recordExceptions&lt;/em&gt;&lt;/strong&gt; listesi kullanarak hata olarak sayılmasını istediğimiz Exception sınıflarını tanımlayabiliriz. Bunlar haricindekiler başarılı olarak sayılacaktır. Ayrıca belirtilen sınıflardan miras almış sınıflar da aynı şekilde ele alınacaktır.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;ignoreExceptions&lt;/em&gt;&lt;/strong&gt; listesi ile görmezden gelinecek Exception sınıflarını tanımlayabiliriz. Bu sınıflar ne başarılı ne de başarısız olarak kabul edilecektir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Retry
&lt;/h2&gt;

&lt;p&gt;Hata ile sonuçlanan bir çağrının otomatik olarak yeniden gönderilmesi amacıyla kullanılır. &lt;/p&gt;

&lt;p&gt;Retry ile alakalı dikkat edilmesi gereken önemli bir nokta, çağrı sonucu çalışan operasyonun &lt;strong&gt;idempotent&lt;/strong&gt; olması, yani tekrarlanan istekte gereksiz olan bulunuyorsa bunun görmezden gelinebilmesidir, aksi takdirde mantık hatalarına yol açabilir. Örneğin operasyon için çağrı yapıldığında, gerekli işlemler sağlıklı bir şekilde gerçekeştirilmiş olsun ancak geri dönüşte bir problem oluşmuş olsun, bu durumda istek tekrarlanacak ve eğer sistem buna hazırlıklı değilse aynı işlemler tekrar yapılmaya çalışılacaktır.&lt;/p&gt;

&lt;p&gt;Retry kullanımında çeşitli değerleri konfigüre edebiliriz ; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;maxAttempts&lt;/strong&gt;: Hata durumunda maksimum deneme sayısını belirtir. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;waitDuration&lt;/strong&gt;: Her bir deneme arasında geçen sabit süreyi belirtir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;enableExponentialBackoff&lt;/strong&gt;: Denemeler arasındaki geçen sürenin sabit olmayıp, exponential şekilde artacağını belirtir. Örneğin, denemeler arasında geçen süreler 2-4-8 şeklinde artar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yeniden deneme durumları istenen şekilde ayarlanabilir. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atılan isteğe bir cevap dönülmüş ise konfigürasyon dosyasına eklenecek &lt;strong&gt;resultPredicate&lt;/strong&gt; değeri ile hangi koşulda retry yapılacağı ayarlanabilir.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;resultPredicate: io.reflectoring.resilience4j.springboot.predicates.ConditionalRetryPredicate&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ConditionalRetryPredicate implements Predicate&amp;lt;SearchResponse&amp;gt; {
 @Override
 public boolean test(SearchResponse searchResponse) {
   if (searchResponse.getErrorCode() != null) {
     return searchResponse.getErrorCode().equals("FS-167");
   } 
   return false;
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;İstek gerçekleştirilirken hata gerçekleşmiş ise &lt;strong&gt;retryExceptionPredicate&lt;/strong&gt; kullanılarak, hata incelenip retry yapılıp yapılmayacağına karar verilebilir veya &lt;strong&gt;retryExceptions&lt;/strong&gt; ve &lt;strong&gt;ignoreExceptions&lt;/strong&gt; değerleri kullanılarak direk olarak sınıflarına göre filtreleme de yapılabilir.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;retryExceptionPredicate: io.github.resilience4j.circuitbreaker.RecordFailurePredicate&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class RecordFailurePredicate implements Predicate&amp;lt;Throwable&amp;gt; {

   @Override
   public boolean test(Throwable throwable) {
       return throwable instanceof IOException || throwable instanceof IgnoredException;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Time Limiter
&lt;/h2&gt;

&lt;p&gt;TimeLimiter, ilgili uca yapılan işlemin en fazla ne kadar zaman alacağını belirlemek için kullanılır.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TimeLimiter sadece asenkron işlemin yapıldığı(&lt;strong&gt;&lt;em&gt;CompletableFuture&lt;/em&gt;&lt;/strong&gt; ile sağlanan) endpoint'lere uygulanabilir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TimeLimiter kullanımında çeşitli değerleri konfigüre edebiliriz;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;timeoutDuration&lt;/strong&gt;: Gelen isteğin zaman aşımı süresini belirtir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cancelRunningFuture&lt;/strong&gt;: Hali hazırda çalışan future için iptal edilip edilemeyeceğini belirtir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Rate Limiter
&lt;/h2&gt;

&lt;p&gt;Sisteme, belirtilen zaman aralığı içerisinde gelebilecek istek sayısını kontrol edebilmemizi sağlar.&lt;/p&gt;

&lt;p&gt;Rate Limiter kullanımında çeşitli değerleri konfigüre edebiliriz;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;limitForPeriod&lt;/strong&gt;: Belirtilen periyot için izin verilecek azami istek sayısır&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;limitRefreshPeriod&lt;/strong&gt;: Verilen limit değerinin geçerli olacağı süreyi belirtir. Süre sonunda istek sayısı sıfırlanır.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;timeoutDuration&lt;/strong&gt;: Limit değere ulaşıldığında, blokalanan thread için kaç saniye bekleneceğini belirtir. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bulkhead
&lt;/h2&gt;

&lt;p&gt;Bulkhead ile gelen eşzamanlı çağrı sayısını sınırlayabiliriz.&lt;/p&gt;

&lt;p&gt;İki şekilde gerçekleştirilebilir ;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SemaphoreBulkhead&lt;/strong&gt; : Gelen isteklerin semafor yardımı ile kilitleme mantığı ile yürütülmesi.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FixedThreadPoolBulkhead&lt;/strong&gt; : Gelen her istek için, oluşturulan thread havuzundan uygun bir thread alınır ve izole bir şekilde işlemler gerçekleştirilir..&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Semafor yaklaşımı için iki değer konfigüre edilebilir;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;maxConcurrentCalls&lt;/strong&gt;: Bulkhead tarafından aynı anda yürütülebilecek, azami istek sayısını belirtir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;maxWaitDuration&lt;/strong&gt;: Belirlenen &lt;strong&gt;maxConcurrentCalls&lt;/strong&gt; sayısının aşımına sebep olan isteğin ne kadar süre bloklanacağını belirtir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thread havuzu yaklaşımı için çeşitli değerler konfigüre edilebilir;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;coreThreadPoolSize&lt;/strong&gt; : Oluşturlan havuz için sabit(minimum) thread miktarını belirtir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;maxThreadPoolSize&lt;/strong&gt; : &lt;strong&gt;coreThreadPoolSize&lt;/strong&gt; miktarından daha fazla thread kullanımı gerektiğinde, geçici şekilde oluşturulabilecek yeni threadlerin azami miktarını belirtir. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;queueCapacity&lt;/strong&gt; : Thread havuzunda uygun thread bulunmadığında gelen isteklerin bekletileceği sıranın kapasitesini belirtir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;keepAliveDuration&lt;/strong&gt; : Geçici oluşturulan threadlerin boşta ne kadar süre bekleyebileceğini belirtir. Bu süre aşımında thread sonlandırılır.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>resilience4j</category>
      <category>java</category>
      <category>faulttolerance</category>
    </item>
    <item>
      <title>Transaction Management ve Spring Boot</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Sun, 14 Aug 2022 11:07:47 +0000</pubDate>
      <link>https://dev.to/emrebasar/transaction-management-ve-spring-boot-1544</link>
      <guid>https://dev.to/emrebasar/transaction-management-ve-spring-boot-1544</guid>
      <description>&lt;h2&gt;
  
  
  Transaction Nedir ?
&lt;/h2&gt;

&lt;p&gt;Transaction, beraberce başarılı veya başarısız olan olaylar serisidir.&lt;br&gt;
Yapılan işlemlerin her birinin başarılı olması durumunda commit edilmesi herhangi birinin başarısız olması &lt;br&gt;
ise işlemlerin tamamının başarısız olarak kabul edilerek rollback yapması olayıdır. Bu işlem bize veri bütünlüğünü sağlar.&lt;/p&gt;
&lt;h2&gt;
  
  
  Transaction Türleri
&lt;/h2&gt;

&lt;p&gt;Transactionlar kullanım yerlerine göre global ve local olarak ikiye ayrılır.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hP5g4_6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjjt93g221qi2utxb1ka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hP5g4_6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjjt93g221qi2utxb1ka.png" alt="local transaction" width="475" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yukarıdaki sipariş örneğinde gösterildiği gibi, kullanıcı monolitik bir sisteme Order isteği gönderdiği zaman, alakalı transactionlar ortak bir veritabanına yazılır. Hata durumunda ise tek bir yapı halinde rollback edilebilir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XuctVQwg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ogcy9emtawq7zyq1w5xg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XuctVQwg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ogcy9emtawq7zyq1w5xg.png" alt="global transaction" width="783" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sistem Monolit yapıdan Mikroservis mimarisine geçirildiğinde, Customer ve Order işlemleri için iki farklı servis oluşturulur ve alakalı veritabanlarıda ayrılmış olur. &lt;br&gt;
Bu durumda iki servis için gerekli olan transactionların ayrı olarak yönetilmesi gerekir. Transaction artık birden çok veritabanında olduğundan, &lt;strong&gt;Distributed Transaction&lt;/strong&gt; olarak kabul edilir.&lt;/p&gt;
&lt;h2&gt;
  
  
  Transaction Özellikleri
&lt;/h2&gt;

&lt;p&gt;Transaction yönetiminde aşağıdaki konular göz önünde bulundurulmalıdır;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Failure recovery (Atomicity, Durability).&lt;/li&gt;
&lt;li&gt;Concurrency control (Isolation, Consistency).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ACID prensiplerinın uygulanması sağlıklı bir transaction gerçekleştirmemizi sağlar.&lt;/p&gt;
&lt;h3&gt;
  
  
  Automicity
&lt;/h3&gt;

&lt;p&gt;Transaction işlemini bir bütün olarak görür. İşlem sırasında birden fazla veritabanı/tablodaki verinin güncellenmesi gerçekleşiyor &lt;br&gt;
ise tüm bunların hepsi birden başarılı olacaktır veya başarısız olacaktır&lt;/p&gt;
&lt;h3&gt;
  
  
  Consistency
&lt;/h3&gt;

&lt;p&gt;Gerçekleştirilen Transaction işleminden etkilenen verilerin başlangıç ve bitiş durumlarının tutarlı olması gereklidir. Transaction sırasında oluşan bir hatanın, sistemin durumunu beklenmeyen bir şekilde etkilemesi engellenir.&lt;/p&gt;
&lt;h3&gt;
  
  
  Isolation
&lt;/h3&gt;

&lt;p&gt;Aynı anda aynı veri üzerinde birden fazla Transaction gerçekleşebilir. Transaction’ların birbirlerinin işlemlerinden etkilenmemesi için işlemlerin Seri olarak yapılması gerekir. Transaction sırasında ilgili ve etkilenecek veri, işlem başarılı veya başarısız olarak sonuçlanana kadar veri setleri kilitlenir.&lt;/p&gt;
&lt;h3&gt;
  
  
  Durability
&lt;/h3&gt;

&lt;p&gt;Transaction sırasında fiziksel veya işlemsel bir hata olması durumunda sistemin kendisini bir önceki geçerli veri durumuna döndürebilme kabiliyetidir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0jYJmcnV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ouvg2da34i5jedt2pax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0jYJmcnV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ouvg2da34i5jedt2pax.png" alt="ACID prensipleri" width="612" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Transaction Yönetimi Nedir?
&lt;/h2&gt;

&lt;p&gt;Kullanılan transactionların ne gibi kurallar dahilinde çalışacağı kontrol edilebilir.&lt;/p&gt;
&lt;h2&gt;
  
  
  Spring Proxy Kullanımı
&lt;/h2&gt;

&lt;p&gt;Spring, Transactional anotasyonu kullanılmış sınıf veya metodlar için direk çağrı yerine, bir proxy kullanır. Bu transaction mantığı ile iş mantığını birbirinden ayırma konusunda yardım eder.&lt;/p&gt;

&lt;p&gt;Örneğin aşağıdaki gibi bir yapıya sahip olalım.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EjhJGCCw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skmepe7md0nxmxljla7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EjhJGCCw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skmepe7md0nxmxljla7m.png" alt="prox1" width="252" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AccountService sınıfı için bir çağrı yapıldığında;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1XtAwwbE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xoilpb9fwl5cw3tz1vfl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1XtAwwbE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xoilpb9fwl5cw3tz1vfl.png" alt="proxy2" width="572" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Burada araya bir proxy yapısı girer ve gerekli sınıfa veya metoda bu yapı üzerinden ulaşırız.&lt;/p&gt;
&lt;h2&gt;
  
  
  Transaction Yönetim Türleri
&lt;/h2&gt;

&lt;p&gt;Spring transaction yönetimi için iki yöntem sunar. Programatik ve Deklaratif&lt;/p&gt;
&lt;h3&gt;
  
  
  Programmatic
&lt;/h3&gt;

&lt;p&gt;Transaction yönetimi(commit, rollback) kodlarının içinde barındıran bir yöntemdir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public void transferMoney(Account from, Account to, double amount, double fee) {
    TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
    TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
    try {
        withdraw(from, amount, fee);
        deposit(to, amount);
        transactionManager.commit(transactionStatus);
    } catch (RuntimeException e) {
        transactionManager.rollback(transactionStatus);
        throw e;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Declarative
&lt;/h3&gt;

&lt;p&gt;Spring altyapısında bazı kurallar çerçevesinde Spring Container tarafından gerçekleştirilir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@Transactional Anotasyonu sayesinde yapılır
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
@Transactional
public void transferMoney(Account from, Account to, double amount, double fee){
    withdraw(from, amount, fee);
    deposit(to, amount);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bu transaction yönetimi şeklinde sahip olduğumuz bazı işlem tipleri vardır.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Propagation tipi&lt;/li&gt;
&lt;li&gt;Isolation seviyesi&lt;/li&gt;
&lt;li&gt;Timeout süresi&lt;/li&gt;
&lt;li&gt;readOnly flag &lt;/li&gt;
&lt;li&gt;Rollback kuralı&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Propagation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Transaction başladıktan sonraki davranışları ele aldığımız özelliktir. Bu tanımlamaya göre sonraki transaction davranışı belirlenir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;REQUIRED Propagation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;REQUIRED, varsayılan propagation tekniğidir. Spring, aktif bir transaction olup olmadığını kontrol eder ve yoksa yeni bir tane oluşturur. Aksi takdirde, işlemler etkin olan transactiona eklenir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(propagation = Propagation.REQUIRED)
public void requiredExample(String user) {
// ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;REQUIRES_NEW Propagation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Var olan transactionu kullanmak yerine, onu askıya alarak yeni bir transaction oluşturmayı zorunlu kılar. Yeni transaction tamamlandığında askıya alınan transactiona geri dönülür.&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(propagation = Propagation.REQUIRES_NEW)
public void requiresNewExample(String user) { 
    // ... 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SUPPORTS Propagation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aktif var olan bir transaction bulunuyorsa ona dahil olur ancak yok ise non-transactional bir davranış sergiler.&lt;br&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(propagation = Propagation.SUPPORTS)
public void supportsExample(String user) { 
    // ... 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NOT_SUPPORTED Propagation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Var olan aktif bir transaction varsa onu kullanmak yerine, onu askıya alarak işlemleri non-transactional olarak gerçekleştirir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void notSupportedExample(String user) { 
    // ... 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MANDATORY  Propagation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aktif bir transaction bulunması durumunda ona dahil olur ancak bulunmadığı takdirde &lt;strong&gt;&lt;em&gt;IllegalTransactionStateException&lt;/em&gt;&lt;/strong&gt; fırlatır.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(propagation = Propagation.MANDATORY)
public void mandatoryExample(String user) { 
    // ... 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NEVER  Propagation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aktif bir transaction bulunması durumunda &lt;strong&gt;&lt;em&gt;IllegalTransactionStateException&lt;/em&gt;&lt;/strong&gt; fırlatır, yoksa işlemleri non-transactional olarak gerçekleştirir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(propagation = Propagation.NEVER)
public void neverExample(String user) { 
    // ... 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Isolation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Her bir transactiondaki veriyi manipule etmek amacıyla kullanılır.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;READ_UNCOMMITTED Isolation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Diğer transactionlarda gerçekleşen veri değişimlerinin, commitlenmeden önce, mevcut transactiondan okunabilmesini sağlar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void log(String message) {
    // ...
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;READ_COMMITTED Isolation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Diğer transactionlarda gerçekleşen veri değişimlerinin, commitlenmeden önce okunmasını engeller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(isolation = Isolation.READ_COMMITTED)
public void log(String message) {
    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;REPEATABLE_READ Isolation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bir silme veya yeni kayıt ekleme işlemi sırasında, aynı anda okuma işlemi yapılabilmesine izin verir.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(isolation = Isolation.REPEATABLE_READ)
public void log(String message) {
// ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SERIALIZABLE Isolation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En yüksek seviye izolasyon yöntemidir. Bir kayıt üzerinde işlem yapılırken, bu kayıt kitlenir ve diğer transactionların üzerinde çalışması engellenir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(isolation = Isolation.SERIALIZABLE)
public void log(String message) {
// ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rollback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Transaction için rollback işlemini gerçekleştirmek ve gerçekleştirmemek istediğimiz Exception tiplerini belirtmemiz mümkündür.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(rollBackFor = NullPointerException.class)
public void method(String message) {
// ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(noRollBackFor = NullPointerException.class)
public void method(String message) {
// ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ayrıca rollBackFor, varsayılan olarak RunTimeException için ayarlanmıştır.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timeout&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Transactionun belirli bir süre geçtikten sonra sonlanamaması durumunda otomatik olarak bitirilmesini sağlar. Varsayılan olarak 60 saniyedir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(timeout = 15)
public void method(String message) {
// ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Read Only&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Transactionunun sadece okuma işlemi için kullanılacağını belirtmek için kullanılır. Veriye erişimin buna göre optimize edilmesini sağlar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Transactional(readOnly = true)
public void method(String message) {
// ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>transaction</category>
      <category>transactionmanagement</category>
      <category>springtransactions</category>
    </item>
    <item>
      <title>JUNIT 4 v JUNIT 5</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Sun, 14 Aug 2022 10:58:44 +0000</pubDate>
      <link>https://dev.to/emrebasar/junit-4-v-junit-5-3f7o</link>
      <guid>https://dev.to/emrebasar/junit-4-v-junit-5-3f7o</guid>
      <description>&lt;ul&gt;
&lt;li&gt;JUnit son versiyonu  JUnit5, Java8'in özelliklerini kullanarak daha okunabiilir, kullanışlı ve esnek bir framework ortaya koymaya çalışmıştır.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Annotations
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5MCQtqro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hn7nv873zgm5g2m0v560.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5MCQtqro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hn7nv873zgm5g2m0v560.png" alt="annotations" width="603" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@TestFactory : Metodun dinamik test olduğunu belirtir.&lt;/li&gt;
&lt;li&gt;@Nested : Test sınıfı içerisinde nested sınıflar tanımlamamıza imkan sağlar.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;@ExtendWith : İsteğe bağlı class veya package eklemek için kullanılır. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Varsayılan olarak hem JUnit 4 hem JUnit 5 için metodlar static olarak tanımlanmalıdır, ancak JUnit 5 @TestInstance(TestInstance.Lifecycle.PER_CLASS) anotasyonu kullanarak static kullanımının zorunluluğunu kaldırabiliyoruz.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Assertions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  JUnit 4
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Junit 4'te, org.junit.Assert, beklenen ve elde edilen sonuçları doğrulamak için tüm assert yöntemlerine sahiptir.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void assertEquals(long expected, long actual)
public static void assertEquals(String message, long expected, long actual)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Hata mesajı için ekstra parametre ilk argüman olarak beklenir. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  JUnit 5
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JUnit 5 ile, org.junit.jupiter.Assertions, yeni olarak assertThrows() ve assertAll() yöntemleri dahil, çoğu assert yöntemini içerir.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void assertEquals(long expected, long actual)
public static void assertEquals(long expected, long actual, String message)
public static void assertEquals(long expected, long actual, Supplier messageSupplier)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hata mesajı için ekstra parametre son argüman olarak beklenir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supplier messageSupplier, olası bir hata durumunda, metod referansı veya lambda operasyonu kullanarak, verilen cevabın dinamik bir şekilde tanımlanabilmesini sağlar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Junit 4'te, bir exceptionın fırlatıldığını kontrol ederken, &lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt;(expected = InterruptedException.class) anotasyoununu kullanırken, JUnit 5 ile aşağıdaki gibi assertThrows kullanarak kontrol yapılabilir.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    @Test
    public void shouldThrowAnCheckedException(){
        Exception exception = Assertions.assertThrows(IOException.class, () -&amp;gt; {
            throw new IOException(
                       "We interrupt this test to throw an checked exception");
        });
     }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Aynı şekilde timeout kontrolu de, &lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt;(timeout = 10), assertTimeout şeklinde değiştirildi.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    @Test
    public void testFailWithTimeout() throws InterrptedException{
        Assertions.assertTimeout(Duration.ofMiilis, () -&amp;gt; Thread.sleep(100); 
    }   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Assumptions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  JUnit 4
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Junit 4'te, org.junit.Assume, bir testin anlamlı olduğu koşullar hakkında varsayımları belirtmek için yöntemler içerir. Bunlar ;

&lt;ul&gt;
&lt;li&gt;assumeFalse()&lt;/li&gt;
&lt;li&gt;assumeNoException()&lt;/li&gt;
&lt;li&gt;assumeNotNull()&lt;/li&gt;
&lt;li&gt;assumeThat()&lt;/li&gt;
&lt;li&gt;assumeTrue()&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Hata mesajı için ekstra parametre ilk argüman olarak beklenir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  JUnit 5
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;JUnit 5 ile, bu varsayımların sayısı düşürülmüştür ve 3 adet varsayım vardır. Ayrıca bu metodları org.junit.jupiter.api.Assumptions içerir hale gelmiştir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assumeFalse()&lt;/li&gt;
&lt;li&gt;assumingThat()&lt;/li&gt;
&lt;li&gt;assumeTrue()&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ayrıca metodlar overload edilebilir olup, gerektiğinde yapılması istenen operasyonlar lambda formunda parametre olarak verilebilir.&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
void testSomething() throws Exception{
  Assumptions.assumingThat("foo".equals("bar"),() -&amp;gt;{
    assertEquals(...);
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test Suite
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Farklı test sınıflarını tek bir yerden çağırıp kullanmak istediğimizde JUnit 4 ile aşağıdaki gibi bir yapı kullanırken,
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
        ExceptionTest.class, 
        TimeoutTest.class
})
public class JUnit4Example 
{
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;JUnit 5 ile Suite yerini SelectPackages ve SelectClasses almıştır. Bu Single Responsibility açısından faydalıdır. Ayrıca @RunWith anotasyonunun yerini @ExtendWith almış ve parametresi JUnitPlatform.class olarak değişmiştir.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.runner.RunWith;

@ExtendWith(JUnitPlatform.class)
@SelectPackages("com.howtodoinjava.junit5.examples")
public class JUnit5Example 
{
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mimari
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;JUnit 4, her şeyi tek bir jar dosyayı altında toplamıştı, bu durum JUnit 5 için farklıdır.

&lt;/li&gt;
&lt;li&gt;JUnit 5, 3 alt elementten oluşur;

&lt;ul&gt;
&lt;li&gt;JUnit Platform : Platformda çalışan yeni test ortamlarını geliştirmek için TestEngine API tanımlar.&lt;/li&gt;
&lt;li&gt;JUnit Jupiter : JUnit anotasyonlarını içerip, bu anotasyonlarla yazılmış testleri çalıştırmak için TestEngine implementasyonlarını içerir.&lt;/li&gt;
&lt;li&gt;JUnit Vintage : JUnit 5 platformunda JUnit 3 ve JUnit 4 yazılı testlerinin çalıştırılmasını sağlar.

&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;JUnit 4 Java5 veya üzeri için iken, JUnit 5 Java8 veya üzeri içindir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Üçüncü Parti Entegrasyonu
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JUnit 4, üçüncü parti yazılımlar için herhangi bir destek içermeyip, bunu Java Reflection ile sağlanmaya çalışılıyordu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JUnit 5 bu amaçla içerdiği JUnit platform ile TestEngine API kullanarak herhangi bir frameworkun çalışmasını destekler.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ek Olarak
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Parameterized Tests
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Parameterized Test, JUnit 4'de çeşitli kütüphaneler ile sağlansa da, JUnit 5 ile tamamen built-in bir hale gelmiştir.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ParameterizedTest
@ValueSource(strings = {"foo", "bar"})
@NullAndEmptySource
void myParameterizedTest(String arg){
  underTest.performAction(arg);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conditional Test Execution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JUnit 5 ile ExecutionCondition API, testleri koşulsal olarak etkinleşirebilir veya devre dışı bırakabilir.


&lt;ul&gt;
&lt;li&gt;@EnabledOnOs ve @DisabledOnOs: Yalnızca belirtilen işletim sistemlerinde bir testi etkinleştirir.

&lt;/li&gt;
&lt;li&gt;@EnabledOnJre ve @DisabledOnJre: Java'nın belirli sürümleri için testin etkinleştirilmesi veya devre dışı bırakılması gerektiğini belirtir.

&lt;/li&gt;
&lt;li&gt;@EnabledIfSystemProperty: JVM sistem özelliğinin değerine dayalı bir testi etkinleştirir.

&lt;/li&gt;
&lt;li&gt;@EnabledIf: Komut dosyasıyla yazılan koşulların karşılanıp karşılanmadığını bir testi etkinleştirmek için komut dosyası mantığı kullanır.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Hystrix</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Sun, 14 Aug 2022 10:45:24 +0000</pubDate>
      <link>https://dev.to/emrebasar/hystrix-4l2m</link>
      <guid>https://dev.to/emrebasar/hystrix-4l2m</guid>
      <description>&lt;h2&gt;
  
  
  Hystrix
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hystrix, dağınık sistemlerde, servisler arasında oluşabilecek gecikme ve hata durumlarında sistemin bu olaylara karşı toleransını arttırmak amacıyla bazı stratejilerin uygulanabilirliğine imkan sağlar. Bunu hizmetler arasındaki erişim noktalarını izole ederek, bunlar arasında kademeli arızaları durdurarak ve dönüş seçenekleri sunarak yapar ve genel esnekliği arttırır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;İstenmeyen bir durum oluştuğunda, bu durumun zincirleme şekilde başka durumlara yol açmadan bir an önce kontrol edilmesi, olabildiğince hızlı tespit ve kurtarma yapılmasını amaçlar ve bu seri kontrol eğilimi ile de gerçek zamana yakın bir monitörleme imkanı sunar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dağıtık mimaride çok fazla bağımlılık bulunur ve bunlar bir aşamada mutlaka hatalı duruma düşerler. Hystrix bu bağımlılıklar arasında bir izolasyon yaratarak 'loose coupling' hedefler.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/Netflix/Hystrix"&gt;https://github.com/Netflix/Hystrix&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Örneğin 10 servisten oluşan ve her servisin has 99.99% uptime sahip olduğu bir uygulamada,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;99.99&lt;sup&gt;10&lt;/sup&gt; = 99.9% uptime&lt;/p&gt;

&lt;p&gt;0.3% of 1 billion requests = 3,000,000 failures&lt;/p&gt;

&lt;p&gt;2+ hours downtime/month even if all dependencies have excellent uptime.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PhyKt0Q8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lr2hrwv6lbw6bwe3efiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PhyKt0Q8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lr2hrwv6lbw6bwe3efiq.png" alt="dependency" width="640" height="582"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mA854bJY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sk2fgl7k8tdhsi6ebc4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mA854bJY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sk2fgl7k8tdhsi6ebc4j.png" alt="dependency" width="640" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Herhangi bir üçüncü parti bağımlılığında oluşan bir gecikme, artan talep ile sistemin bütün kaynaklarını kullanmaya başlayıp, sistem genelinde bir duraksamaya sebep olacaktır.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  İçerdiği Tasarım Prensipleri
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bir bağımlılığın kaynakların kullanımını domine etmemesi.&lt;/li&gt;
&lt;li&gt;En kısa sürede sistemi hata durumuna düşürerek, cevap oluşturup yükten kurtulmak.&lt;/li&gt;
&lt;li&gt;Hata durumunda en uygun yerde bir geri dönüş(fallback) mantığı gerçekleştirerek, kullanıcıyı korumak.&lt;/li&gt;
&lt;li&gt;Çeşitli izolasyon teknikleri(bulkhead, swimlane, ve circuit breaker) ile bağımlılığı azaltmak.&lt;/li&gt;
&lt;li&gt;Hatanın keşfinde ve kurtarılmasında optimizasyon.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Nasıl Gerçekleştiriliyor?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Harici sistemlere (veya "bağımlılıklara") yapılan tüm çağrıları, tipik olarak ayrı bir thread içinde yürütülen bir HystrixCommand veya HystrixObservableCommand nesnesine sarmak (Bu açıdan Command Pattern benzerliği vardır).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bir isteğe cevap geciktiğinde, belli bir eşik değerin üzerinde gecikme oluşursa time-out atılması sağlanır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Her dependency için bir thread-pool oluşturulur ve eğer bu pool gelen istekler ile dolarsa istek anında reddedilir ve gereksiz bekleme ve kaynak harcanması engellenir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bir servisin hata yüzdesi bir eşiği geçerse, belirli bir servise yönelik tüm istekleri belirli bir süre boyunca manuel olarak veya otomatik olarak durdurmak için bir circuit breaker kullanır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Çağrıları sarmalayan yapılar içerisinde olası hatalı durumlarda izlenecek mantık gerçekleştirilerek sağlam ve kullanışlı bir sistem oluşturulur.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vQ_MDcIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gp5xwtcuf56l7hmyzdd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vQ_MDcIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gp5xwtcuf56l7hmyzdd2.png" alt="dependency" width="640" height="869"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Bulkhead
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4TQ19uLS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qz7ydjbb00fvwcl4017h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4TQ19uLS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qz7ydjbb00fvwcl4017h.png" alt="bulkhead" width="475" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Her bir tipteki istek için bir thread pool oluşturup, bir istek tipinin bütün kaynakları kullanıp diğer requestlerin de gecikmesine engel olmasını engeller.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PGjY3Cg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n73yoaizh33y5muan2ne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PGjY3Cg2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n73yoaizh33y5muan2ne.png" alt="threads seperated" width="880" height="405"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Circuit Breaker
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Bir thread pool içerisinde, request sayısı ve thread-pool boyutu oranı artarak belli bir eşik değeri üzerine çıkarsa, servise giden bağlantının kesilip(circuit-open) isteklerin anında cevaplanması ve gecikmenin engellenmesini sağlar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aynı mantık geciken cevaplardan ziyade, hata oluşan isteklerde de uygulanabilir. Belli bir değerin üzerinde hata oluştuğunda bağlantı kırılarak, fazla sayıda hatanın oluşması engellenir ve gerekli aksiyonların alınabilmesi için imkan oluşturulur.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TiZdr16A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sggua7by3gq1ydvi93w0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TiZdr16A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sggua7by3gq1ydvi93w0.png" alt="circuit breaking" width="880" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    @SyncCallLogger
    @Override
    @HystrixCommand&lt;span class="o"&gt;(&lt;/span&gt;fallbackMethod &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sorgulaTahakkukFallbackMethod"&lt;/span&gt;,
            commandProperties &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;@HystrixProperty&lt;span class="o"&gt;(&lt;/span&gt;name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"execution.isolation.strategy"&lt;/span&gt;, value &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"SEMAPHORE"&lt;/span&gt;&lt;span class="o"&gt;)})&lt;/span&gt;
    public GumrukEttnSorgulaResponseDTO sorgulaTahakkukGumrukten&lt;span class="o"&gt;(&lt;/span&gt;GumrukEttnSorgulaRequestDTO gumrukEttnSorgulaRequestDTO&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;restTemplate.postForObject&lt;span class="o"&gt;(&lt;/span&gt;gumrukConfiguration.getMaliyews&lt;span class="o"&gt;()&lt;/span&gt;.getSorgulaTahakkuk&lt;span class="o"&gt;()&lt;/span&gt;, gumrukEttnSorgulaRequestDTO, GumrukEttnSorgulaResponseDTO.class&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hytrix sistemlerde gereksiz işlemlerin önlenmesi için iyi bir çözüm ancak artık bakımı yapılmadığı için yakın zamanda benzerlerinin arkasında kalması ve talepleri yerine getirememesi durumu da olası. Kullanımı durumunda bu durum göz önünde bulundurulmalı.&lt;/p&gt;

</description>
      <category>hystrix</category>
      <category>java</category>
      <category>circuitbreake</category>
      <category>faulttolerance</category>
    </item>
    <item>
      <title>SOLID Prensipleri</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Tue, 17 Aug 2021 13:46:10 +0000</pubDate>
      <link>https://dev.to/emrebasar/solid-prensipleri-1a92</link>
      <guid>https://dev.to/emrebasar/solid-prensipleri-1a92</guid>
      <description>&lt;h1&gt;
  
  
  SOLID Prensipleri
&lt;/h1&gt;

&lt;p&gt;SOLID Prensiplerin temel amacı modüler bir yapı sağlayarak tekrar kullanılabilirliği, test edilebilirliği, bakımı ve genişletilmesini kolaylaştırmaktır. Yazılımı daha kolay gerçekleştirilebilir hale getirip, beklenmedik etkileri engellemeyi amaçlar.&lt;/p&gt;




&lt;h3&gt;
  
  
  Single Responsibility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bir class veya  modül yalnızca bir işten sorumlu olmalıdır, aynı anda birbirinden farklı aktörler için hizmet vermemelidir. Aksi taktirde sorumluluklarından birinde yapacağımız bir değişiklik istenmeyen yerlerde hatalara sebep olabilir. Bir class veya modül için tanımlama yaparken tanım ne kadar uzuyorsa ve ne kadar çok "ve" kullanıyorsak, bu konseptten o kadar uzaklaşıyoruz demektir.

&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qg1unjuv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--RDU8cD1Y--/c_imagga_scale%2Cf_auto%2Cfl_progressive%2Ch_900%2Cq_auto%2Cw_1600/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tq7o4zx8mb59yv8yc5hl.png" alt=""&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Open-Closed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bir class için ana davranışı değiştirmeden, bu davranışının üzerine, izin verilen ölçüde, yeni eklemeler yapılabilir olması gerekir. Bu yaklaşım, class için önemli olan temel elemanları koruyarak, halihazırda bu classtan faydalanan birimlerde sorun oluşmasını engeller. Geliştirmelerde Single Responsibility ile ters düşmemek adına eklenen özelliklerin ana davranışa bağlı olmasına dikkat edilmelidir.

 &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CxMTWwPq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://badearobert.ro/blog/wp-content/uploads/2018/05/Open-Closed.png" alt=""&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Liskov Substitution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bir class üzerinden inheritance söz konusu olduğunda, üretilen child classların parent classın hizmetlerini yerine getirebilir olması beklenir. Child class istekler üzerine daha spesifik cevaplar verebilir olsa da verdiği cevaplar parent classın cevapları ile tutarlı olmalıdır.
Burda child classlara esnek bir çalışma alanı bırakabilmek için parent classları olabildiğince abstract yapmak akılcı olacaktır.

&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VzRedCA8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/gokhan-gokalp.com/wp-content/uploads/2015/06/liskov.jpg%3Fssl%3D1" alt=""&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Interface Segregation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bir classtan beklenen aksiyonlar, o classın yapmakta yetersiz olduğu veya çalışma alanında olmayan aksiyonlar olmamalıdır, bu tanımlamalar gereksiz olup okunabilirlik açısından kötü bir etki yaratabilir. Bu kapsamda temelde aynı özelliklere sahip olsa da, farklı aksiyonlar gerçekleştirmek üzere geliştirilen classlar için, aksiyonlara yönelik interfaceler kullanılmalıdır.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependency Inversion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bir class ile kullandığı araçlar arasında doğrudan değil de dolaylı bir ilişki olmalıdır. Bu ilişki interface aracılığıyla sağlanmalıdır. Bu sayede aracın nasıl çalıştığı class tarafından bilinmek zorunda değildir, aracın bağlantıyı sağlayan interface'in gerekliliklerini sağlaması yeterli olur. Bu durum classın bağımlılığını azaltmış olur ayrıca tekrar kullanılabilirlik de arttırılmış olur.

&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nb9t99jl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1280/1%2Am-CMwIOkrY6-Y1lkE3kLfw.jpeg" alt=""&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SPRING ve SOLID Prensipleri
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Single Responsibility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Spring Frameworkü ile SR arasındaki ilişkiyi basitçe Controller, Service ve Repository classları üzerinden anlatmaya çalışırsak;

&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xxvz4IaA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/1%2AkazAwhquHXpLT8qiQwZu1Q.png" alt=""&gt;

Bir para akışı modeli için, her düzeyde, gelir ve gider için gereken aksiyonları içeren classları oluşturmak, her classın bellirli ve alakalı use case kontrolleri yapmasını sağlar ve SR arttırır.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Open-Closed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Aynı model üzerinden devam edilirse, Open-Closed ilkesi doğrultusunda en az değişiklik ile yeni özellik eklemeleri yapılabilmesi için ilk olarak, service ve controller arasındaki bağlantıyı azaltmak gereklidir. Bunu da araya bir başka interface katmanı ekleyerek yapabiliriz. Böylelikle service katmanını inject eden controller servicedeki değişikliklerden en az şekilde etkilenir.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IwaNJMFx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/568/1%2AnbK0eDoEyZNa229TH9ycPQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IwaNJMFx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/568/1%2AnbK0eDoEyZNa229TH9ycPQ.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
Bir adım daha gidip, yapıyı yeni özellik eklemelerine de uygun hale getirmek için, örnek olarak gelir gider hesplamaları gibi bir özellik eklemek için de aynı yapı kullanılır.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZfMuY0Vw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/410/1%2A--xmI3vOX_8xnX8kN0PDZw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZfMuY0Vw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/410/1%2A--xmI3vOX_8xnX8kN0PDZw.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Burda ServiceImpl classlarının hesaplama classlarına bağımlılığı en az seviyede tutulmuş olur ve daha sonradan gelecek başka türde hesaplamalar da bu CalculatorService arayüzü üzerinden gerçekleştirilebilir.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Liskov Substitution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CashFlow projesi üzerinde geliştirme için devam edersek Liskov için yapabileceğimiz şey, service classlarını düzenlemek olacak. İlk olarak Controller classları için kullanılan serviceler ile hesaplama için kullanılan serviclerin ayrımını yapıyoruz ki hesaplama servisinin repository sınıfları ile olan gereksiz bağlantısı ortadan kalksın. Bunları kendi entityleri ile başka bir package içerisie taşıyoruz.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DrcCMSY5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/1%2ACCxROVMCYCoG1HBT3waYSA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DrcCMSY5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/1%2ACCxROVMCYCoG1HBT3waYSA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Daha sonra Service türleri için de bir abstraction oluşturarak bağımlılığı daha da azaltıyoruz.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NbhMmfuG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/461/1%2AH4Rin7QjOEw1w6D3TB70CA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NbhMmfuG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/461/1%2AH4Rin7QjOEw1w6D3TB70CA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Burdaki bir diğer önemli nokta da her iki service tipinin de Service parent classının gerekliliklerini yerine getirerek LS prensibine uyuyor olmasıdır.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface Segregation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ek olarak bir tane daha, gelir ve gider arasında dönüştürme yapan bir service yaratmak istediğimizde bunları tek bir service altında değil de, bir parentdan implement ederek oluşturduğumuzda, sınıfların ortak bir arayüzü implement edip gereksiz methodları override etmeye çalışmasını engellemiş oluruz.

&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d9_FUN3s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/1%2AcT8R_47qtz1jENtcOc645Q.png" alt=""&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependency Inversion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dependency Inversion Prensibi, High-Level elemanların, Low-Level elemanlara, abstraction ile bağlanması gerektiğini söyler.&lt;/p&gt;

&lt;p&gt;Önceki 4 prensip ile beraber yapı aşağıdaki gibi bir hal aldı ve Dependency Inversion sağlanmış oldu.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fzXpPT1N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/1%2AOEaUIcsNle-3d3hN6huuAA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fzXpPT1N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/700/1%2AOEaUIcsNle-3d3hN6huuAA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Görüldüğü üzere farklı katmanlardaki elemanlar birbirlerine doğrudan değil, Dependency Inversion doğrultusunda arayüzler aracılığıyla soyutlanarak bağlanmış durumdadır.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dependency Inversion, Dependency Injection ve Inversion of Control
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dependency Inversion farklı seviyelerdeki modül veya sınıfların arasındaki iletişimin arayüzler aracılığıyla sağlanarak bağımlılığı azaltır ancak yine de instance tanımlamaları hala tanımlanan sınıf tarafından yapıldığı için bağımlılık tam manasıyla sağlanmış değildir.
Bunu aşmak için Dependency Injection kullanılır. Dependency Injection, Inversion of Control prensibini implement eden bir design patern’dır. Bağımlılıklar class’a dışarıdan “enjekte” edilir.

&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6_YUo9lZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2rnzzpmlkweafesfar50.png" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Site Reliability Engineering</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Tue, 17 Aug 2021 13:13:08 +0000</pubDate>
      <link>https://dev.to/emrebasar/site-reliability-engineering-2926</link>
      <guid>https://dev.to/emrebasar/site-reliability-engineering-2926</guid>
      <description>&lt;h1&gt;
  
  
  Site Reliability Engineering
&lt;/h1&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Güvenilir olmayan yazılımlar, işletmelere bir çok alanda olumsuz etkilere sebep olabilir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;İhtiyaç duyulan düzeyde güvenilirlik sağlanmalıdır, aksi takdirde kaynak kaybına yol açar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sağlanan güvenilirlik sürdürülebilir olmalıdır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SRE ve DevOps aynı amaca hizmet eden iki farklı yaklaşımdır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SRE de kullanılan iki ana konsept: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SLI ve SLO&lt;/li&gt;
&lt;li&gt;Suçlama Yapılmayan Otopsiler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;;iki konsept de verimli döngüler oluşturmayı hedefler. &lt;/p&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SLI ve SLO
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;SRE ile ilgili kararlar gelişimin bütün paydaşları ile beraber verilir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SLI -&amp;gt; sistemin belli ölçekteki başarı sıklığı.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SLO , bu başarının hedeflenen düzeyidir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hedeflenen SLO dan kalan kaynağa hata bütçesi denir ve bu kısım ,SLO kaybı olmadığı takdirde, sistem gelişimi için kullanılabilir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hata bütçeleri genellikle ayarlanan bir süre için hesaplanır.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Suçlama Yapılmayan Otopsiler
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Olası bir istenmeyen durumda hatayı yapan kişiyle ilgilenmek yerine, kişinin bu hatayı yapmasına sebep olan şeylere odaklanılır.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SRE ilkeleri
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SRE için zahmetten(toil) kaçınmak için otomasyon kullanımı önemli bir husustur.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gereğinden fazla zahmetle uğraşılması daha önce belirtilen verimli döngülerin oluşturulması ve devamlılığını baltalar.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Clean Code</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Tue, 17 Aug 2021 13:05:13 +0000</pubDate>
      <link>https://dev.to/emrebasar/clean-code-2af2</link>
      <guid>https://dev.to/emrebasar/clean-code-2af2</guid>
      <description>&lt;h3&gt;
  
  
  TEMİZ KOD
&lt;/h3&gt;

&lt;p&gt;Temiz kodlama hakkında notlar genel başlıklar halinde aşağıdaki gibidir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Konseptin Genel Gereksinimleri
&lt;/h2&gt;

&lt;p&gt;Herhangi bir kodlama elemanında tekrarlamalar yapılmamalı, olabildiğince generic bir tasarım yapılmalıdır.&lt;br&gt;
Kod baştan aşağı bir anlam içermeli ve aynı bağlamdaki elemanlar alakalı yerlerde kullanılmalıdır.&lt;br&gt;
Modüller arası ilişkiyi en aza indirip, olabildiğince esnek ve bağımsız bir yapı yaratılmalıdır.&lt;/p&gt;

&lt;h2&gt;
  
  
  İsimlendirme
&lt;/h2&gt;

&lt;p&gt;Değişken : Ne hakkında bilgi taşıdığı net anlaşılmalıdır&lt;/p&gt;

&lt;p&gt;Sınıf : Sorumlulukları kapsayan isimler olmalıdır, fiil içermemelidir.&lt;/p&gt;

&lt;p&gt;Method: Ne iş yaptığını "Tek Görevlilik" çerçevesinde anlatmalıdır.&lt;/p&gt;

&lt;p&gt;Boolean : Cevabının değişkenler ile alakalı olması gerekli, bir durumun kontrolünü açıkça belirtebilmelidir. &lt;br&gt;
                  Binary sorulara cevap verebilmelidir.&lt;/p&gt;

&lt;p&gt;İsimlendirmeleri anlık değil, genel kapsamda yapıp kodu anlaşılır yapmalı, yapılmak isteneni en uygun&lt;br&gt;
şekilde ifade edecek şekilde tasarlanmalıdır. Kısaltma kullanmak, bizim için anlaşılır olsa da başkası için&lt;br&gt;
olamayabileceği için, pek iyi değildir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Koşullar
&lt;/h2&gt;

&lt;p&gt;Kontrol edilen durumun ne olduğunu en iyi anlatacak şekilde tasarlanmalı, koşul kısmını olabildiğince&lt;br&gt;
kısa tutmalı, gerekirse başka bir değişken kullanarak enkapsüle etmeli.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fonksiyonlar
&lt;/h2&gt;

&lt;p&gt;Tekrardan kaçınmak temel amacıyla küçük ve tek amaca hizmet eden kod blokları kullanılmalı ve verilen &lt;br&gt;
parametreler ve sayıları da bu tasarımı desteklemeli.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exception Handling
&lt;/h2&gt;

&lt;p&gt;İşlerin ters gitmesi durumuna karşılık önlem alınmalı ve istenmeyen durumlarla karşılaşıldığı zaman&lt;br&gt;
uygun bilgilendirme ile birlikte gerekli aksiyonlar gerçekleştirilmeli.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sınıflar
&lt;/h2&gt;

&lt;p&gt;Olabildiğince küçük ve kapsamı net olarak belli olmalı. Koşullara göre kapsamı genişleyen yapılar olmamalı.&lt;br&gt;
İyi organize edilmiş, diğer modüllerle gereğinden fazla alaka  kurmayan sınıflar gelecek değişimlerde kolaylık&lt;br&gt;
sağlar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yorum Satırları
&lt;/h2&gt;

&lt;p&gt;Yorum satırları direk olarak kodu açıklamak için değil, kodun gerçek manada kendini anlatmaya yetersiz &lt;br&gt;
kaldığı durumlarda kullanılmalıdır. Her zaman ilk öncelik yorum satırı yerine ne yaptığını net bir şekilde&lt;br&gt;
açıklayan kod blokları olmalıdır, bunun mümkün olmadığı yerlerde yorum satırları kullanılmalıdır.&lt;/p&gt;

&lt;h2&gt;
  
  
  Biçim
&lt;/h2&gt;

&lt;p&gt;Baştan aşağı kodu okurken bir örgü içerisinde olmalı, alakalı değişkenler ve metodlar bir arada olmalı.&lt;/p&gt;

&lt;h2&gt;
  
  
  Güvenlik
&lt;/h2&gt;

&lt;p&gt;Kullandığımız dilin bize verdiği imkanlar doğrultusunda güvenli bir kod yazmalıyız, kod elemanlarının &lt;br&gt;
kullanılması gereken kapsamlar dışında kullanılmamasını sağlamalıyız. Bu hem güvenliğin yanında esnekliği,&lt;br&gt;&lt;br&gt;
bakım yapılabilirliği, anlaşılabilirliği ve test edilebilirliği konusunda da yardımcı olur. &lt;br&gt;
Örneğin Javada kullanılan private ve public anahtar kelimeleri. &lt;/p&gt;

&lt;h2&gt;
  
  
  Testler
&lt;/h2&gt;

&lt;p&gt;Testler bir kodun güvenilirliğini ve bakım-edilebilirliği konusunda önemlidir. Okunabilir kodlar yazmak&lt;br&gt;
kadar okunabilir testler yazmak da önemlidir. Kapsamı belli, bağımsız ve hızlı testler kullanılmalıdır.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CI-CD</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Tue, 17 Aug 2021 13:01:06 +0000</pubDate>
      <link>https://dev.to/emrebasar/ci-cd-2boh</link>
      <guid>https://dev.to/emrebasar/ci-cd-2boh</guid>
      <description>&lt;h1&gt;
  
  
  CI/CD
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Deployment süreçlerindeki tekrar eden işleri otomatize etmek için kullanılır.&lt;/li&gt;
&lt;li&gt;İnsan payını en az indirmeyi amaçlar ve hızlı bir gelişim süreci sağlar.&lt;/li&gt;
&lt;li&gt;Paketin kullanıcıya sunmaya ne derecede hazır olduğunu denetler.&lt;/li&gt;
&lt;li&gt;Integration ve Delivery aşamalarından oluşur.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Continuous Integration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Kaynak kod üzerinde değişiklik yapıldıktan sonra sistemin çalışır durumda olduğunu ve değişikliğin sorun yaratmadığını tespit etmek için kullanılır.&lt;/li&gt;
&lt;li&gt;Sorun halinde gerekli kişilerin bilgilendirilmesi sağlanır.&lt;/li&gt;
&lt;li&gt;Bir uygulamadaki değişiklikler birleştirildiğinde, değişikliklerin uygulamayı bozmadığından emin olmak için uygulamayı otomatik olarak oluşturarak ve farklı düzeylerde testler ile doğrular.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Continuous Delivery
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; Başarılı olan bir yapının bir ortama ototmatik olarak aktarılmasıdır.&lt;/li&gt;
&lt;li&gt; Yeni bir sürüm dağıtıldığında geçici kesintilerden etkilenmeyecek şekilde tasarlanmalıdır.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CI/CD
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Değişiklikler günde birçok kez ana kod dalında birleştirir&lt;/li&gt;
&lt;li&gt;Her kod, otomatik bir kod oluşturma ve test sırasını tetiklemek için birleştirilir&lt;/li&gt;
&lt;li&gt;Sistem tekrar eden sürümleri destekleyecek şekilde tasarlanmalıdır.&lt;/li&gt;
&lt;li&gt;Sorunları gerçek zamanlı olarak tespit etmeye çalışılmalıdır. &lt;/li&gt;
&lt;li&gt;Kod test odaklı geliştirmeye çalışılmalıdır.&lt;/li&gt;
&lt;li&gt;Çeşitli araçlar yardımıyla entgre edilir. Bunlar; Jenkins, TeamCity, GitLab, CircleCI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Faydaları
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Otomatik dağıtım ve testler gerçekleştirerek verimliliği artırır.&lt;/li&gt;
&lt;li&gt;En son yazılım sürümünü destekleyerek risklere karşı önlem alır.&lt;/li&gt;
&lt;li&gt;Teslim süreleri kısalır.&lt;/li&gt;
&lt;li&gt;Kaynak daha verimli kullanılır.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>API ?</title>
      <dc:creator>Mustafa Emre Başar</dc:creator>
      <pubDate>Tue, 17 Aug 2021 12:57:00 +0000</pubDate>
      <link>https://dev.to/emrebasar/api-5gpn</link>
      <guid>https://dev.to/emrebasar/api-5gpn</guid>
      <description>&lt;h2&gt;
  
  
  API ve API Yönetimi
&lt;/h2&gt;




&lt;ul&gt;
&lt;li&gt;Application Programing Interface&lt;/li&gt;
&lt;li&gt;Yazılımın asıl çalışma şekli ve karmaşıklığı ile ilgilenmeden, bu yazılımla iletişim kurma yoludur&lt;/li&gt;
&lt;li&gt;Bu yapı sayesinde yazılım programları birbirlerine istek gönderebilir ve gelen istekleri işleyebilir.&lt;/li&gt;
&lt;li&gt;API yönetiminin 4 temel unsuru vardır;

&lt;ul&gt;
&lt;li&gt;Gateway : WebClient ile iletişimde olduğu service veya sistem arasında bulunur. Gerçekleşen requestlerin kontrolünü sağlar.&lt;/li&gt;
&lt;li&gt;Developer Portal : Geliştiricilerin API ile alakalı belgelemeleri paylaşabilecekleri bir platformdur.&lt;/li&gt;
&lt;li&gt;Life Cycle Manager : API gerçekleşimi boyunca adımların doğruluğunu kontrol eder.&lt;/li&gt;
&lt;li&gt;Reporting Analytic: API performansı hakkında gözlemleme yapmayı sağlar.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  OPEN API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Belirli tanımlamaları kullanarak(YAML veya JSON dosyaları),API iç yapısında neler olduğunu anlamaya gerek kalmadan ,API kullanımı gerçekleştirilir.&lt;/li&gt;
&lt;li&gt;Kolay entegrasyon sayesinde kısa sürede kullanıma hazır hale gelebilirler.&lt;/li&gt;
&lt;li&gt;Bulut tabanlı yapısı, internet erişimi olan her yerde kullanıma izin verir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  REST API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Temel olarak Client ve Server arasında iletişim oluşturmak için kullanılır&lt;/li&gt;
&lt;li&gt;REST açılımı Representational State Transfer .&lt;/li&gt;
&lt;li&gt;RESTFUL Service, iletişim kurmak için REST kullanan bir Service demektir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Faydaları
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Basit ve standartlaştırılmış, projeniz için yapılandırması kolay.&lt;/li&gt;
&lt;li&gt;Scalable and stateles, Service ne kadar karmaşık olursa olsun veya hangi veriler hangi durumda olursa olsun kullanılabilir.&lt;/li&gt;
&lt;li&gt;Yüksek performans.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Genel Konsept
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Server ve Client arasındaki iletişim, client tarafından yollanan request ve buna cevap olarak server tarafından verilen response ile sağlanır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client ve server arası iletişimdeki CRUD operasyonlarını HTTP metodları ile yönetir&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Client tarafından gönderilen request;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operasyon(Http metodlarından bir tanesi)&lt;/li&gt;
&lt;li&gt;Endpoint&lt;/li&gt;
&lt;li&gt;Parametler/Body&lt;/li&gt;
&lt;li&gt;Header
içerir.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server tarafından gönderilen response JSON formatında bir yanıt olur.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
