{"id":4143,"date":"2022-10-29T20:17:19","date_gmt":"2022-10-29T18:17:19","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=4143"},"modified":"2022-10-30T13:13:09","modified_gmt":"2022-10-30T12:13:09","slug":"building-microservices-by-using-dapr-and-net-with-minimum-effort-01","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/","title":{"rendered":"Dapr ve .NET Kullanarak Minimum Efor ile Microservice&#8217;ler Geli\u015ftirmek &#8211; 01"},"content":{"rendered":"<p>Bildi\u011fimiz gibi her ge\u00e7en g\u00fcn teknoloji ve al\u0131\u015fkanl\u0131klar\u0131m\u0131z s\u00fcrekli de\u011fi\u015fmekte. \u00d6zellikle pandemi s\u00fcrecinden sonra dijitalle\u015fmeye ve teknolojiye olan e\u011filim olduk\u00e7a artm\u0131\u015f durumda. Durum b\u00f6yleyken bizlerde geli\u015ftiriciler olarak bu de\u011fi\u015fimlere ve isteklere adapte olabilmek ad\u0131na, geli\u015ftirdi\u011fimiz uygulamalar\u0131n m\u00fcmk\u00fcn olabildi\u011fince <strong>portable<\/strong> ve <strong>scalable<\/strong> yap\u0131da olmalar\u0131na dikkat etmekteyiz.<\/p>\n<p>Maalesef uygulamalar\u0131m\u0131z\u0131 geli\u015ftirirken sadece business fonksiyonalitelerine odaklanabilmemizin yan\u0131 s\u0131ra, uygulamalar\u0131m\u0131z\u0131n portable, scalable ve resilient bir yap\u0131da olabilmeleri ad\u0131na d\u00fc\u015f\u00fcnmemiz ve odaklanmam\u0131z gereken bir \u00e7ok farkl\u0131 endi\u015fe ve problemleri de bulunmakta.<\/p>\n<p>\u00d6rne\u011fin <strong>pub\/sub<\/strong> kullanabilmem i\u00e7in hangi service bus library&#8217;sini kullanaca\u011f\u0131m, <strong>state store<\/strong> edebilmek i\u00e7in ne gerekli, uygulamalar aras\u0131 ileti\u015fimimi nas\u0131l <strong>resilient<\/strong>\u00a0ve <strong>reliable<\/strong>\u00a0bir hale getirebilirim veya <strong>observability<\/strong> sa\u011flayabilmek i\u00e7in uygulamalar\u0131mdan telemetry verilerini nas\u0131l toplayabilirim gibi bir \u00e7ok d\u00fc\u015f\u00fcnmemiz gereken farkl\u0131 soru ve incelememiz\/denememiz ve kurmam\u0131z gereken farkl\u0131 \u00e7\u00f6z\u00fcmler ve library&#8217;ler bulunmakta. Bunlar\u0131n yan\u0131 s\u0131ra kullanmaya karar verdi\u011fimiz library&#8217;leri ve yakla\u015f\u0131mlar\u0131 da standardize edebilmek i\u00e7in kendi shared library&#8217;lerimizi geli\u015ftirme gibi ihtiya\u00e7lar\u0131m\u0131z da olabiliyor.<\/p>\n<p>\u0130ki seri olarak ele alaca\u011f\u0131m bu konunun ilk b\u00f6l\u00fcm\u00fcnde ise distributed ortamlarda kar\u015f\u0131m\u0131za \u00e7\u0131kabilecek ihtiya\u00e7lar\u0131 kolayca ele al\u0131p abstract bir hale getirebilmemizi ve h\u0131zl\u0131 bir \u015fekilde ilgili business fonksiyonalite&#8217;lerine odaklanabilmemizi sa\u011flayan <strong><em>Dapr<\/em><\/strong> projesinden bahsedip, ard\u0131ndan \u00f6rnek bir uygulama geli\u015ftirece\u011fiz. Bir sonraki makalede ise farkl\u0131 <strong><em>Azure<\/em><\/strong> servislerini kullanarak geli\u015ftirmi\u015f olaca\u011f\u0131m\u0131z uygulamay\u0131 <strong><em>Azure Container Apps<\/em><\/strong> \u00fczerine nas\u0131l deploy edebilece\u011fimize bir bakaca\u011f\u0131z.<\/p>\n<h2>Distributed Application Runtime (Dapr)<\/h2>\n<p><em>Dapr<\/em> k\u0131saca kolay ve h\u0131zl\u0131 bir \u015fekilde portable, reliable ve resilient microservice&#8217;ler geli\u015ftirebilmemize olanak tan\u0131yan <em>Microsoft<\/em> taraf\u0131ndan 2019 y\u0131l\u0131nda duyurulmu\u015f bir event-driven runtime&#8217;d\u0131r. Platform ve yaz\u0131l\u0131m dili agnostic bir \u015fekilde <strong>cloud-native<\/strong> uygulama geli\u015ftirme s\u00fcre\u00e7lerini olduk\u00e7a kolayla\u015ft\u0131rmakla beraber, bizlerin ilgili core business fonksiyonalite&#8217;lerine odaklanabilmesine olanak tan\u0131maktad\u0131r. Ayr\u0131ca bir <em><strong>CNCF<\/strong><\/em> projesidir.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2022\/08\/dapr-overview.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4145 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/08\/dapr-overview.jpg\" alt=\"\" width=\"2426\" height=\"1214\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/dapr-overview.jpg 2426w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/dapr-overview-300x150.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/dapr-overview-1024x512.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/dapr-overview-768x384.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/dapr-overview-1536x769.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/dapr-overview-2048x1025.jpg 2048w\" data-sizes=\"(max-width: 2426px) 100vw, 2426px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2426px; --smush-placeholder-aspect-ratio: 2426\/1214;\" \/><\/a><\/p>\n<p>Bildi\u011fimiz gibi container&#8217;lar d\u00fcnyas\u0131nda <strong>sidecar<\/strong> model&#8217;i olduk\u00e7a \u00f6nemli bir yere sahiptir. Bizlere mevcut container&#8217;lar\u0131m\u0131za dokanmadan onlar\u0131n fonksiyonalitelerini geni\u015fletebilmemize olanak tan\u0131maktad\u0131r. <em>Dapr<\/em>&#8216;da uygulamalar\u0131m\u0131z\u0131n bir par\u00e7as\u0131 olarak <strong>sidecar model&#8217;i<\/strong> ile \u00e7al\u0131\u015fmaktad\u0131r.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2022\/08\/sidecar-generic.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4149 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/08\/sidecar-generic.png\" alt=\"\" width=\"617\" height=\"403\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/sidecar-generic.png 617w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/08\/sidecar-generic-300x196.png 300w\" data-sizes=\"(max-width: 617px) 100vw, 617px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 617px; --smush-placeholder-aspect-ratio: 617\/403;\" \/><\/a><\/p>\n<p><em>Dapr<\/em> ile microservice&#8217;ler geli\u015ftirebilmek i\u00e7in <em>SDK<\/em>&#8216;ler oldu\u011fu gibi, ilgili uygulamalar <em>HTTP<\/em>\/<em>gRPC<\/em> \u00e7a\u011fr\u0131lar\u0131 yapabildi\u011fi s\u00fcrece <em>SDK<\/em>&#8216;ler olmadan da geli\u015ftirme yap\u0131labilmektedir. Ayr\u0131ca platform ba\u011f\u0131ms\u0131z olarak \u00e7al\u0131\u015fabilmektedir.<\/p>\n<p>\u015eimdi <em>Dapr<\/em>&#8216;\u0131n building block&#8217;lar\u0131na k\u0131saca bir g\u00f6z atal\u0131m.<\/p>\n<h3>Dapr Building Blocks<\/h3>\n<p><em>Dapr<\/em> birden \u00e7ok ba\u011f\u0131ms\u0131z ve farkl\u0131 endi\u015feleri \u00e7\u00f6zebilmemize olanak sa\u011flayan, standardize edilmi\u015f a\u015fa\u011f\u0131daki gibi farkl\u0131 <em>API<\/em>&#8216;lardan olu\u015fmaktad\u0131r.<\/p>\n<ul>\n<li>Service-to-service invocation<\/li>\n<li>State management<\/li>\n<li>Publish and subscribe<\/li>\n<li>Resource bindings and triggers<\/li>\n<li>Actors<\/li>\n<li>Observability<\/li>\n<li>Secrets<\/li>\n<li>Configuration<\/li>\n<li>Distributed Lock<\/li>\n<\/ul>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi cloud-native bir microservice mimarisi design edebilmemiz i\u00e7in gerekli olan t\u00fcm fonksiyonaliteleri farkl\u0131 building block&#8217;lar alt\u0131nda bizlere sa\u011flamaktad\u0131r. G\u00fczel taraf\u0131 ise uygulamalar\u0131m\u0131z sadece <em>Dapr<\/em> building block&#8217;lar\u0131n\u0131 bilmektedir, herhangi bir external library&#8217;lere ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 bulunmamaktad\u0131r. Ayr\u0131ca bu building block&#8217;lardan ister birini, istersek de hepsini kullanabiliriz. Building block&#8217;lar hakk\u0131nda daha detayl\u0131 bilgilere ise, <em><a href=\"https:\/\/docs.dapr.io\/concepts\/building-blocks-concept\/\" target=\"_blank\" rel=\"noopener\">buradan<\/a><\/em> eri\u015febilirsiniz.<\/p>\n<h3>Dapr Components<\/h3>\n<p><a href=\"\/wp-content\/uploads\/2022\/09\/concepts-components.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4153 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/09\/concepts-components.jpg\" alt=\"\" width=\"2521\" height=\"1433\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/concepts-components.jpg 2521w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/concepts-components-300x171.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/concepts-components-1024x582.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/concepts-components-768x437.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/concepts-components-1536x873.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/concepts-components-2048x1164.jpg 2048w\" data-sizes=\"(max-width: 2521px) 100vw, 2521px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2521px; --smush-placeholder-aspect-ratio: 2521\/1433;\" \/><\/a><\/p>\n<p>Bir di\u011fer \u00f6nemli konu ise component&#8217;ler. Component&#8217;ler i\u00e7in k\u0131saca building block&#8217;lar\u0131n \u00e7al\u0131\u015fabilmesi i\u00e7in gerekli olan <strong>concrete<\/strong> implementation&#8217;lar diyebiliriz. <em>Dapr<\/em>\u00a0<strong>pluggable<\/strong> bir yap\u0131ya sahip oldu\u011fu i\u00e7in, ayr\u0131ca bu component&#8217;leri kolay bir \u015fekilde farkl\u0131 component&#8217;ler ile de de\u011fi\u015ftirebilmekteyiz.<\/p>\n<p>\u00d6rne\u011fin default kurulumda pub\/sub building block&#8217;u i\u00e7in <em>Redis<\/em> component&#8217;i kullan\u0131lmaktad\u0131r. Bunu istersek <em>RabbitMQ<\/em> component&#8217;i ile uygulama taraf\u0131nda herhangi bir de\u011fi\u015fikli\u011fe gerek olmadan de\u011fi\u015ftirebilmekteyiz. Kula\u011fa ho\u015f geliyor, de\u011fil mi?<\/p>\n<pre>components % more pubsub.yaml \r\napiVersion: dapr.io\/v1alpha1\r\nkind: Component\r\nmetadata:\r\n  name: pubsub\r\nspec:\r\n  type: pubsub.redis\r\n  version: v1\r\n  metadata:\r\n  - name: redisHost\r\n    value: localhost:6379\r\n  - name: redisPassword\r\n    value: \"\"\r\n<\/pre>\n<p>Ayr\u0131ca component&#8217;ler g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi <em>CustomResourceDefinition<\/em> (<em>CRD<\/em>) olarak tan\u0131mlanmaktad\u0131r ve <em>Dapr<\/em>&#8216;\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131 herhangi bir ortamda kullan\u0131labilmektedir. Component schema&#8217;s\u0131 ve format&#8217;lar\u0131 hakk\u0131nda detayl\u0131 bilgiye ise <em><a href=\"https:\/\/docs.dapr.io\/operations\/components\/component-schema\/\" target=\"_blank\" rel=\"noopener\">buradan<\/a><\/em> eri\u015febilirsiniz.<\/p>\n<h2>Bir \u00d6rnek Ger\u00e7ekle\u015ftirelim<\/h2>\n<p>\u015eimdi <em>Dapr<\/em> ile uygulama geli\u015ftirme s\u00fcre\u00e7lerini daha iyi anlayabilmek ad\u0131na, <em>Dapr<\/em>&#8216;\u0131n bir ka\u00e7 building block&#8217;unu kullanarak basit bir <b>ShoppingCart<\/b> ve <strong>Recommendation<\/strong>\u00a0service&#8217;lerini\u00a0geli\u015ftirelim.<\/p>\n<h3>\u0130lk Olarak Dapr&#8217;\u0131 Kural\u0131m<\/h3>\n<blockquote><p><strong><em>NOT<\/em><\/strong>: Kurulum i\u015fleminden \u00f6nce \u00f6nerilen development ortam\u0131 i\u00e7in <em>Docker<\/em>&#8216;a sahip olmam\u0131z gerekmektedir.<\/p><\/blockquote>\n<p><em>Dapr<\/em> ile ilgili \u00e7e\u015fitli i\u015flemleri ger\u00e7ekle\u015ftirebilmek i\u00e7in \u00f6ncelikle <em>Dapr CLI<\/em>&#8216;a sahip olmam\u0131z gerekmektedir. Bunun i\u00e7in <em><a href=\"https:\/\/docs.dapr.io\/getting-started\/install-dapr-cli\/\" target=\"_blank\" rel=\"noopener\">buradaki<\/a><\/em> ad\u0131mlar\u0131 takip ederek, ilgili environment i\u00e7in <em>Dapr CLI<\/em>&#8216;\u0131 install edelim. Ard\u0131ndan development i\u015flemlerini ger\u00e7ekle\u015ftirebilmemiz i\u00e7in <em>Dapr<\/em>&#8216;\u0131, self-hosted mode&#8217;da local olarak initialize edelim. Bunun i\u00e7in &#8220;<em>dapr init<\/em>&#8221; komutunu \u00e7al\u0131\u015ft\u0131rmam\u0131z yeterli olacakt\u0131r.<\/p>\n<p>Ard\u0131ndan &#8220;<em>docker ps<\/em>&#8221; komutu ile <em>Dapr<\/em>&#8216;\u0131n \u00e7al\u0131\u015f\u0131p \u00e7al\u0131\u015fmad\u0131\u011f\u0131n\u0131 kontrol edebiliriz.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4157 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com.jpg\" alt=\"\" width=\"2416\" height=\"272\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com.jpg 2416w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com-300x34.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com-1024x115.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com-768x86.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com-1536x173.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/09\/docker-ps-dapr-com-2048x231.jpg 2048w\" data-sizes=\"(max-width: 2416px) 100vw, 2416px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2416px; --smush-placeholder-aspect-ratio: 2416\/272;\" \/><\/a><\/p>\n<p>Bu noktada g\u00f6rebilece\u011fimiz gibi &#8220;<em>dapr<\/em>&#8220;, &#8220;<em>zipkin<\/em>&#8221; ve &#8220;<em>redis<\/em>&#8221; container&#8217;lar\u0131 \u00e7al\u0131\u015f\u0131yor durumda. <em>Dapr<\/em> default olarak metrikleri toplayabilmek i\u00e7in <em>Zipkin<\/em>&#8216;i, state-store ve messaging i\u00e7in ise <em>Redis<\/em>&#8216;i kullanmaktad\u0131r. Ayr\u0131ca component&#8217;ler <em>Windows<\/em> i\u00e7in &#8220;<strong><em>%USERPROFILE%\\.dapr<\/em><\/strong>&#8221; klas\u00f6r\u00fc, <em>Linux<\/em> i\u00e7in ise &#8220;<strong><em>$HOME\/.dapr<\/em><\/strong>&#8221; klas\u00f6r\u00fc alt\u0131nda tan\u0131mlanmaktad\u0131r.<\/p>\n<p>Bu noktaya kadar local development i\u00e7in <em>Dapr<\/em> kurulum i\u015flemini tamamlad\u0131k. Daha sonras\u0131nda ise farkl\u0131 component&#8217;lerin kullan\u0131mlar\u0131na da de\u011finiyor olaca\u011f\u0131z.<\/p>\n<h3>ShoppingCart&#8217;\u0131 Geli\u015ftirelim<\/h3>\n<p>\u015eimdi h\u0131zl\u0131 ve basit bir \u015fekilde bir sepet uygulamas\u0131 geli\u015ftirme ihtiyac\u0131m\u0131z oldu\u011funu varsayal\u0131m. Bu uygulamay\u0131 geli\u015ftirebilmek i\u00e7in bir state-store&#8217;a ihtiyac\u0131m\u0131z olacak. \u00c7\u00fcnk\u00fc sepet durumlar\u0131n\u0131 tutmam\u0131z gerekmektedir. \u015eimdi teknoloji gibi herhangi bir konu hakk\u0131nda bir \u015fey d\u00fc\u015f\u00fcnmeden, <em>Dapr<\/em> ile nas\u0131l kolay bir \u015fekilde bu uygulamay\u0131\u00a0geli\u015ftirebilece\u011fimize bir bakal\u0131m.<\/p>\n<p>\u0130lk olarak <strong>DaprShop.ShoppingCart.API<\/strong>\u00a0ad\u0131nda bir <em><strong>.NET 6 API<\/strong><\/em> projesi olu\u015ftural\u0131m ve i\u00e7erisinden &#8220;<em>WeatherForecast<\/em>&#8221; ile ilgili olan kod par\u00e7alar\u0131n\u0131 silelim. Ard\u0131ndan projeye &#8220;<em>Dapr.Client<\/em>&#8221; ve &#8220;<em>Dapr.AspNetCore<\/em>&#8221; library&#8217;lerini <em>NuGet<\/em> \u00fczerinden dahil edelim. B\u00f6ylece <em>Dapr<\/em> ile geli\u015ftirmelerimizi daha efektif bir \u015fekilde ger\u00e7ekle\u015ftirebilece\u011fiz.<\/p>\n<p>\u015eimdi <strong>Domain<\/strong> ad\u0131nda bir klas\u00f6r olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki gibi sepet i\u00e7in ihtiya\u00e7 duyaca\u011f\u0131m\u0131z modelleri tan\u0131mlayal\u0131m.<\/p>\n<pre>using System;\r\nnamespace DaprShop.ShoppingCart.API.Domain;\r\n\r\npublic class ShoppingCartItem\r\n{\r\n\tpublic string ProductId { get; set; } = String.Empty;\r\n\tpublic string ProductName { get; set; } = String.Empty;\r\n\tpublic decimal Price { get; set; }\r\n\tpublic int Quantity { get; set; }\r\n}\r\n<\/pre>\n<pre>using System;\r\nnamespace DaprShop.ShoppingCart.API.Domain;\r\n\r\npublic class ShoppingCart\r\n{\r\n    public ShoppingCart() =&gt; Items = new List&lt;ShoppingCartItem&gt;();\r\n\r\n    public string UserId { get; set; } = String.Empty;\r\n    public List&lt;ShoppingCartItem&gt; Items { get; set; }\r\n}\r\n<\/pre>\n<p>Ard\u0131ndan <strong>Services<\/strong> ad\u0131nda bir klas\u00f6r olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki gibi i\u00e7erisinde sepet implementasyonunu ger\u00e7ekle\u015ftirelim.<\/p>\n<pre>using System;\r\nnamespace DaprShop.ShoppingCart.API.Services;\r\n\r\npublic interface IShoppingCartService\r\n{\r\n    Task&lt;Domain.ShoppingCart&gt; GetShoppingCartAsync(string userId);\r\n    Task AddItemToShoppingCartAsync(string userId, Domain.ShoppingCartItem item);\r\n}\r\n<\/pre>\n<pre>using Dapr.Client;\r\nusing DaprShop.ShoppingCart.API.Domain;\r\n\r\nnamespace DaprShop.ShoppingCart.API.Services;\r\n\r\npublic class ShoppingCartService : IShoppingCartService\r\n{\r\n    private readonly DaprClient;\r\n    private static readonly string storeName = \"statestore\";\r\n\r\n\tpublic ShoppingCartService(DaprClient daprClient)\r\n\t{\r\n        _daprClient = daprClient;\r\n\t}\r\n\r\n    public async Task AddItemToShoppingCartAsync(string userId, ShoppingCartItem item)\r\n    {\r\n        Domain.ShoppingCart shoppingCart = await GetShoppingCartAsync(userId);\r\n\r\n        ShoppingCartItem? existingItem = shoppingCart.Items.Where(x =&gt; x.ProductId == item.ProductId).FirstOrDefault();\r\n        if(existingItem != null)\r\n        {\r\n            existingItem.Quantity += item.Quantity;\r\n        }\r\n        else\r\n        {\r\n            shoppingCart.Items.Add(item);\r\n        }\r\n\r\n        await _daprClient.SaveStateAsync(storeName, userId, shoppingCart);\r\n    }\r\n\r\n    public async Task&lt;Domain.ShoppingCart&gt; GetShoppingCartAsync(string userId)\r\n    {\r\n        var shoppingCart = await _daprClient.GetStateAsync&lt;Domain.ShoppingCart&gt;(storeName, userId.ToString());\r\n        if(shoppingCart == null)\r\n        {\r\n            shoppingCart = new Domain.ShoppingCart()\r\n            {\r\n                UserId = userId\r\n            };\r\n        }\r\n\r\n        return shoppingCart;\r\n    }\r\n}\r\n\r\n\r\n<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi<strong> AddItemToShoppingCartAsync<\/strong> ve <strong>GetShoppingCartAsync<\/strong> method&#8217;lar\u0131n\u0131 implemente ederken, state-store i\u00e7in herhangi bir teknoloji veya bir library d\u00fc\u015f\u00fcnmedik. Sadece <em>Dapr<\/em>&#8216;\u0131n sunmu\u015f oldu\u011fu <strong>state-store building block<\/strong>&#8216;unu <strong>DaprClient<\/strong> arac\u0131l\u0131\u011f\u0131yla kullan\u0131p, implementasyon i\u015flemlerini ger\u00e7ekle\u015ftirdik.<\/p>\n<p>Kullanm\u0131\u015f oldu\u011fumuz <strong>storeName<\/strong> field&#8217;\u0131nda ise, <em>Dapr<\/em>&#8216;\u0131n kullanmak istedi\u011fimiz state-store component&#8217;inin ad\u0131n\u0131 belirttik. Bu noktada default olarak gelen state-store component&#8217;inin ad\u0131n\u0131 kulland\u0131k. Bu default de\u011fere ise ilgili &#8220;<em>components<\/em>&#8221; klas\u00f6r\u00fc alt\u0131ndaki &#8220;<em>statestore.yaml<\/em>&#8221; dosyas\u0131n\u0131n &#8220;<em>metadata<\/em>&#8221; b\u00f6l\u00fcm\u00fc alt\u0131ndan ula\u015fabiliriz.<\/p>\n<p>Bu default de\u011fer ile ise default olarak gelen <em>Redis <\/em>component&#8217;ini kullanm\u0131\u015f olduk. Dilersek farkl\u0131 ihtiya\u00e7lar i\u00e7in kullanabilmek \u00fczere <em>Azure CosmosDB<\/em>&#8216;yi kullanan bir ba\u015fka state-store component&#8217;i de tan\u0131mlayabiliriz. B\u00f6ylece herhangi bir teknolojiyi farkl\u0131 noktalarda istedi\u011fimiz gibi kullanabilir ve de\u011fi\u015ftirebiliriz.<\/p>\n<p>E\u011fer <em>Dapr<\/em> <em>SDK<\/em>&#8216;ini de kullanmasayd\u0131k, bu i\u015flemi yine a\u015fa\u011f\u0131daki gibi basit bir \u015fekilde <em>HTTP<\/em> \u00fczerinden ger\u00e7ekle\u015ftirebilirdik.<\/p>\n<pre>curl -X POST http:\/\/localhost:\/v1.0\/state\/statestore\/ \\\r\n  -H \"Content-Type: application\/json\" \\\r\n  -d '[\r\n        {\r\n          \"key\": \"key\",\r\n          \"value\": \"value\"\r\n        }\r\n      ]'<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi <em>Dapr<\/em>, uygulamalar\u0131m\u0131z\u0131 h\u0131zl\u0131 bir \u015fekilde geli\u015ftirebilmemiz i\u00e7in bize olduk\u00e7a esnek bir yap\u0131 sunmaktad\u0131r.<\/p>\n<p>\u015eimdi <strong>ShoppingCartController<\/strong> ad\u0131nda bir controller ekleyelim ve a\u015fa\u011f\u0131daki gibi <strong>ShoppingCartService<\/strong>&#8216;i kullanarak endpoint&#8217;leri de implemente edelim.<\/p>\n<pre>using Microsoft.AspNetCore.Mvc;\r\nusing DaprShop.ShoppingCart.API.Services;\r\nusing Domain = DaprShop.ShoppingCart.API.Domain;\r\n\r\nnamespace DaprShop.Basket.API.Controllers;\r\n\r\n[ApiController]\r\n[Route(\"api\/shopping-cart\")]\r\npublic class ShoppingCartController : ControllerBase\r\n{\r\n    private readonly IShoppingCartService _shoppingCartService;\r\n\r\n    public ShoppingCartController(IShoppingCartService shoppingCartService)\r\n    {\r\n        _shoppingCartService = shoppingCartService;\r\n    }\r\n\r\n    [HttpGet(\"{userId}\")]\r\n    public async Task&lt;ActionResult&lt;Domain.ShoppingCart&gt;&gt; Get(string userId)\r\n    {\r\n        Domain.ShoppingCart shoppingCart = await _shoppingCartService.GetShoppingCartAsync(userId);\r\n\r\n        return Ok(shoppingCart);\r\n    }\r\n\r\n    [HttpPost(\"{userId}\/items\")]\r\n    public async Task&lt;ActionResult&lt;Domain.ShoppingCart&gt;&gt; Post(string userId, Domain.ShoppingCartItem item)\r\n    {\r\n        try\r\n        {\r\n            await _shoppingCartService.AddItemToShoppingCartAsync(userId, item);\r\n            return Ok();\r\n        }\r\n        catch (Exception ex)\r\n        {\r\n            return BadRequest(ex);\r\n        }\r\n    }\r\n}<\/pre>\n<p>Ard\u0131ndan <strong>Program.cs<\/strong> dosyas\u0131n\u0131 a\u015fa\u011f\u0131daki gibi d\u00fczenleyelim ve gerekli injection ve configuration i\u015flemlerini ger\u00e7ekle\u015ftirelim.<\/p>\n<pre>using DaprShop.ShoppingCart.API.Services;\r\n\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\n\/\/ Add services to the container.\r\nbuilder.Services.AddDaprClient();\r\nbuilder.Services.AddScoped&lt;IShoppingCartService, ShoppingCartService&gt;();\r\n\r\nbuilder.Services.AddControllers();\r\nbuilder.Services.AddEndpointsApiExplorer();\r\nbuilder.Services.AddSwaggerGen();\r\n\r\nvar app = builder.Build();\r\n\r\n\/\/ Configure the HTTP request pipeline.\r\nif (app.Environment.IsDevelopment())\r\n{\r\n    app.UseSwagger();\r\n    app.UseSwaggerUI();\r\n}\r\n\r\napp.MapControllers();\r\n\r\napp.Run(\"http:\/\/localhost:5000\");<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi\u00a0<strong>AddDaprClient<\/strong> extension method&#8217;unu kullanarak, <em>Dapr<\/em>&#8216;\u0131 service collection i\u00e7erisine dahil ettik.<\/p>\n<p>Bu noktaya kadar h\u0131zl\u0131 bir \u015fekilde basit bir sepet uygulamas\u0131 tasarlad\u0131k. \u015eimdi ise recommendation service tak\u0131m\u0131n\u0131n kullan\u0131c\u0131lara ilgilendikleri \u00fcr\u00fcnler hakk\u0131nda \u00f6nerilerde bulunabilmelerini sa\u011flayacak bir \u00f6zellik geli\u015ftirmemizin istendi\u011fini varsayal\u0131m. Bu noktada bir kullan\u0131c\u0131 sepetine bir \u00fcr\u00fcn ekledi\u011finde, bu \u00fcr\u00fcn bilgilerini i\u00e7eren bir <strong>event<\/strong> publish etmek istiyoruz. B\u00f6ylece recommendation service tak\u0131m\u0131n\u0131 \u00fcr\u00fcnler hakk\u0131nda bilgilendirilebilir.<\/p>\n<p>\u015eimdi ise bu i\u015flemi <em>Dapr<\/em>&#8216;\u0131n sunmu\u015f oldu\u011fu <strong>pub\/sub building block<\/strong>&#8216;u ile kolayca nas\u0131l halledebiliriz bir bakal\u0131m.<\/p>\n<p>\u0130lk olarak solution&#8217;a <strong>DaprShop.Contracts<\/strong> ad\u0131nda bir class library ekleyelim ve i\u00e7erisinde a\u015fa\u011f\u0131daki gibi publish etmek istedi\u011fimiz event&#8217;i tan\u0131mlayal\u0131m.<\/p>\n<pre>namespace DaprShop.Contracts\r\n{\r\n\tpublic class ProductItemAddedToShoppingCartEvent\r\n\t{\r\n\t\tpublic string UserId { get; set; } = string.Empty;\r\n\t\tpublic string ProductId { get; set; } = string.Empty;\r\n\t}\r\n}<\/pre>\n<p>Ard\u0131ndan <strong>DaprShop.ShoppingCart.API<\/strong> projesine referans olarak ekleyelim.<\/p>\n<p>\u015eimdi implemente etmi\u015f oldu\u011fumuz <strong>AddItemToShoppingCartAsync <\/strong>method&#8217;unu event publish edebilmek i\u00e7in a\u015fa\u011f\u0131daki gibi refactor edelim.<\/p>\n<pre>public async Task AddItemToShoppingCartAsync(string userId, ShoppingCartItem item)\r\n{\r\n    Domain.ShoppingCart shoppingCart = await GetShoppingCartAsync(userId);\r\n\r\n    ShoppingCartItem? existingItem = shoppingCart.Items.Where(x =&gt; x.ProductId == item.ProductId).FirstOrDefault();\r\n    if(existingItem != null)\r\n    {\r\n        existingItem.Quantity += item.Quantity;\r\n    }\r\n    else\r\n    {\r\n        shoppingCart.Items.Add(item);\r\n    }\r\n\r\n    await _daprClient.SaveStateAsync(storeName, userId, shoppingCart);\r\n\r\n    var productItemAddedToShoppingCartEvent = new Contracts.ProductItemAddedToShoppingCartEvent()\r\n    {\r\n        UserId = userId,\r\n        ProductId = item.ProductId\r\n    };\r\n\r\n    const string pubsubName = \"pubsub\";\r\n\tconst string topicNameOfShoppingCartItems = \"daprshop.shoppingcart.items\";\r\n\r\n\tawait _daprClient.PublishEventAsync(pubsubName, topicNameOfShoppingCartItems, productItemAddedToShoppingCartEvent);\r\n}<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi yine <strong>DaprClient<\/strong> \u00fczerinden <strong>PublishEventAsync<\/strong> method&#8217;unu kullanarak, <strong>ProductItemAddedToShoppingCartEvent<\/strong> &#8216;ini kolayca publish edebiliyoruz. State-store i\u00e7in yapt\u0131\u011f\u0131m\u0131z gibi pub\/sub component&#8217;inin ad\u0131n\u0131 ve event&#8217;i publish etmek istedi\u011fimiz topic&#8217;i belirtmemiz yeterlidir.<\/p>\n<p>\u015eimdi ise bu event&#8217;i nas\u0131l consume edebiliriz k\u0131sm\u0131na bir bakal\u0131m.<\/p>\n<h3>Recommendation API&#8217;\u0131 Geli\u015ftirelim<\/h3>\n<p>Yine ilk olarak <strong>DaprShop.Recommendation.API<\/strong>\u00a0ad\u0131nda bir <em><strong>.NET 6 API<\/strong><\/em> projesi olu\u015ftural\u0131m ve i\u00e7erisinden &#8220;<em>WeatherForecast<\/em>&#8221; ile ilgili olan kod par\u00e7alar\u0131n\u0131 silelim. Ard\u0131ndan &#8220;<em>Dapr.AspNetCore<\/em>&#8221; library&#8217;sini <em>NuGet<\/em> \u00fczerinden projeye dahil edelim ve <strong>DaprShop.Contracts <\/strong>class library&#8217;sini de referans olarak ekleyelim.<\/p>\n<p>\u015eimdi <strong>RecommendationController<\/strong> ad\u0131nda bir controller ekleyelim ve a\u015fa\u011f\u0131daki gibi <strong>ProductItemAddedToShoppingCartEvent<\/strong> &#8216;ini dinleyebilece\u011fimiz method&#8217;u implemente edelim. B\u00f6ylece herhangi bir kullan\u0131c\u0131 sepetine bir \u00fcr\u00fcn ekledi\u011finde, bu bilgileri farkl\u0131 \u00f6neriler ger\u00e7ekle\u015ftirebilmek \u00fczere saklayabilece\u011fiz.<\/p>\n<pre>using Dapr;\r\nusing Microsoft.AspNetCore.Mvc;\r\n\r\nnamespace DaprShop.Recommendation.API.Controllers\r\n{\r\n\t[ApiController]\r\n\t[Route(\"api\/recommendations\")]\r\n\tpublic class RecommendationController : ControllerBase\r\n\t{\r\n\t\tprivate const string PubsubName = \"pubsub\";\r\n\t\tprivate const string TopicNameOfShoppingCartItems = \"daprshop.shoppingcart.items\";\r\n\r\n\t\t[Topic(PubsubName, TopicNameOfShoppingCartItems)]\r\n\t\t[Route(\"products\")]\r\n\t\t[HttpPost]\r\n\t\tpublic ActionResult AddProduct(Contracts.ProductItemAddedToShoppingCartEvent productItemAddedToShoppingCartEvent)\r\n\t\t{\r\n\t\t\tConsole.WriteLine($\"New product has been added into shopping cart. Product Id: {productItemAddedToShoppingCartEvent.ProductId} User Id: {productItemAddedToShoppingCartEvent.UserId}\");\r\n\r\n\t\t\treturn Ok();\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi <strong>ProductItemAddedToShoppingCartEvent<\/strong> &#8216;ine subscribe olabilmek i\u00e7in tek yapt\u0131\u011f\u0131m\u0131z, controller i\u00e7erisinde bir method tan\u0131mlamak ve <strong>Topic<\/strong> attribute&#8217;\u00fcn\u00fc kullanarak ilgili <em>Dapr<\/em> pub\/sub component&#8217;inin ad\u0131 ile birlikte ilgili topic&#8217;ini belirtmek oldu. Bu noktada da yine herhangi bir service bus library&#8217;si, messaging teknolojisi vs d\u00fc\u015f\u00fcnmedik.<\/p>\n<p>Arka planda ise <em>Dapr<\/em> pub\/sub building block&#8217;u, pub\/sub component&#8217;i ile ileti\u015fime ge\u00e7mektedir ve uygulamam\u0131z ad\u0131na subscription i\u015flemini ilgili topic i\u00e7in ger\u00e7ekle\u015ftirmektedir. B\u00f6ylece ilgili topic&#8217;e ne zaman yeni bir event gelirse, bu event&#8217;i bu noktada consume edebilece\u011fiz.<\/p>\n<p>Genel olarak <em>Dapr<\/em>&#8216;\u0131n iyi design edilmi\u015f <strong>encapsulation<\/strong>&#8216;lar\u0131 sayesinde, g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi uygulamalar\u0131m\u0131z olduk\u00e7a ba\u011f\u0131ml\u0131l\u0131ktan uzaklar ve daha esnek olarak hareket edebilmektedirler. Ayr\u0131ca <em>Dapr<\/em>&#8216;\u0131 yeni geli\u015ftirmekte oldu\u011fumuz uygulamalar i\u00e7in kullanman\u0131n yan\u0131 s\u0131ra, herhangi bir ba\u011f\u0131ml\u0131l\u0131k getirmedi\u011fi i\u00e7in <strong>mevcut<\/strong> uygulamalar\u0131m\u0131z i\u00e7erisinde de kullanabilmekteyiz.<\/p>\n<p>Bunun yan\u0131nda pub\/sub building block&#8217;u bizlere <strong>at-least-once message delivery<\/strong> garantisi de sunmaktad\u0131r ve farkl\u0131 message broker&#8217;lar ile de \u00e7al\u0131\u015fabilmektedir.<\/p>\n<p>\u015eimdi <strong>Program.cs<\/strong> dosyas\u0131n\u0131 a\u015fa\u011f\u0131daki gibi d\u00fczenleyelim ve gerekli configuration&#8217;lar\u0131 ger\u00e7ekle\u015ftirelim.<\/p>\n<pre>var builder = WebApplication.CreateBuilder(args);\r\n\r\n\/\/ Add services to the container.\r\n\r\nbuilder.Services.AddControllers().AddDapr();\r\nbuilder.Services.AddEndpointsApiExplorer();\r\nbuilder.Services.AddSwaggerGen();\r\n\r\nvar app = builder.Build();\r\n\r\n\/\/ Configure the HTTP request pipeline.\r\nif (app.Environment.IsDevelopment())\r\n{\r\n\tapp.UseSwagger();\r\n\tapp.UseSwaggerUI();\r\n}\r\n\r\napp.UseCloudEvents();\r\napp.MapControllers();\r\napp.MapSubscribeHandler();\r\n\r\napp.Run(\"http:\/\/localhost:6000\");<\/pre>\n<p>Burada ise <b>AddDapr <\/b>extension method&#8217;unu kullanarak, <em>Dapr<\/em>&#8216;\u0131 <em>MVC<\/em> pipeline&#8217;\u0131na dahil ediyoruz. Ayr\u0131ca <em>Dapr<\/em> event format\u0131 olarak <strong>CloudEvents<\/strong> specification&#8217;\u0131n\u0131 kulland\u0131\u011f\u0131 i\u00e7in, gelen event&#8217;lerin otomatik olarak unwrap olabilmesi ad\u0131na <em>CloudEvents<\/em>&#8216;i de <em>ASP.NET Core<\/em> middleware&#8217;ine dahil ediyoruz.<\/p>\n<p>Eklemi\u015f oldu\u011fumuz <strong>MapSubscribeHandler<\/strong> extension method&#8217;u ise, <em>Dapr<\/em> subscribe endpoint&#8217;ini <em>API<\/em>&#8216;a eklemektedir. B\u00f6ylece bu endpoint call edildi\u011finde, otomatik olarak <em>API<\/em> i\u00e7erisinde <strong>Topic<\/strong> attribute&#8217;\u00fcn\u00fc kullanarak tan\u0131mlam\u0131\u015f oldu\u011fumuz action&#8217;lar\u0131 bulmakta ve <em>Dapr<\/em>&#8216;a ilgili topic&#8217;ler i\u00e7in subscription i\u015flemlerini ger\u00e7ekle\u015ftirmesini s\u00f6ylemektedir.<\/p>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi hepsi bu kadar. Her iki service&#8217;i de \u00e7ok fazla bir efor harcamadan, herhangi farkl\u0131 bir library ihtiya\u00e7lar\u0131 olmadan kolay bir \u015fekilde geli\u015ftirdik.<\/p>\n<h2>Resiliency<\/h2>\n<p><em>Dapr<\/em>&#8216;\u0131n ayr\u0131ca <strong>resilient<\/strong> state&#8217;e sahip service&#8217;ler geli\u015ftirebilmemize olanak sa\u011flad\u0131\u011f\u0131ndan bahsetmi\u015ftik. Dapr bizlerin \u00e7ok fazla d\u00fc\u015f\u00fcnmeden ve efor harcamadan cloud-native microservice&#8217;ler geli\u015ftirebilmemize olanak tan\u0131rken, microservice&#8217;lerimizin reliable bir state&#8217;e ve fault tolerance&#8217;a sahip olabilmelerini de sa\u011flamaktad\u0131r. Bu konuda <em>Dapr<\/em> bizlere farkl\u0131 noktalarda farkl\u0131 se\u00e7enekler sunmaktad\u0131r.<\/p>\n<p><em>Dapr<\/em> state-store building block&#8217;u, &#8220;<em>Strong<\/em>&#8221; ve &#8220;<em>Eventual<\/em>&#8221; olmak \u00fczere iki farkl\u0131 <strong>consistency<\/strong> modelini desteklemektedir. Ayr\u0131ca eventual consistency ise default davran\u0131\u015f\u0131d\u0131r. State-store \u00f6zelinde consistency davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirebilmek i\u00e7in ise, client \u00fczerinden a\u015fa\u011f\u0131daki gibi <strong>StateOptions<\/strong> belirtmemiz yeterli olmaktad\u0131r.<\/p>\n<pre>new StateOptions() { Consistency = ConsistencyMode.Strong}<\/pre>\n<p><strong>Conflict&#8217;leri<\/strong> y\u00f6netebilmek i\u00e7in ise &#8220;<em>Optimistic Concurrency Control<\/em>&#8221; u desteklemektedir. Yakla\u015f\u0131m olarak update ise conflict&#8217;lerin \u00e7ok nadir oldu\u011funu varsaymaktad\u0131r. Yani genellikle i\u015flemlerin sorunsuz ger\u00e7ekle\u015fece\u011fini varsayar. Aksi durumda ise tahmin edebilece\u011fimiz \u00fczere tekrar edilece\u011fini. B\u00f6ylece performans etkisi olmadan conflict durumlar\u0131n\u0131 efektif bir \u015fekilde ele alabilmektedir. Bu i\u015flemleri ise <em>ETag<\/em>&#8216;leri kullanarak ger\u00e7ekle\u015ftirmektedir.<\/p>\n<p><em>ETag<\/em> belirtilmedi\u011fi s\u00fcrece default olarak &#8220;<em>last-write-wins<\/em>&#8221; stratejisini kullanmaktad\u0131r. Bu stratejinin uygun olmad\u0131\u011f\u0131 durumlarda ise <em>ETag<\/em> belirterek a\u015fa\u011f\u0131daki gibi &#8220;<em>first-write-wins<\/em>&#8221; stratejisini de kullanabilmekteyiz.<\/p>\n<pre>var (shoppingCart, etag) = await _daprClient.GetStateAndETagAsync(storeName, userId.ToString());\r\n\r\n\/\/ ...\r\n\r\nawait _daprClient.TrySaveStateAsync(storeName, userId, shoppingCart, etag);<\/pre>\n<p>Ayr\u0131ca her state-store i\u00e7in farkl\u0131 <strong><em>TTL<\/em><\/strong> configuration&#8217;lar\u0131 da uygulayabilmekteyiz.<\/p>\n<p><em>Dapr<\/em> bunlara ek olarak <strong>retries\/back-offs<\/strong>, <strong>circuit breakers<\/strong>, <strong>timeouts<\/strong> gibi \u00f6zelliklere daha granular bir \u015fekilde sahip olabilmemiz i\u00e7in, fault tolerance resiliency policy&#8217;ler tan\u0131mlayabilmemize de olanak tan\u0131maktad\u0131r.<\/p>\n<p>Policy&#8217;ler de component&#8217;ler ile ayn\u0131 klas\u00f6r alt\u0131nda a\u015fa\u011f\u0131daki gibi tan\u0131mlanmaktad\u0131r.<\/p>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: <em>Dapr<\/em>&#8216;\u0131 self-hosted mode&#8217;da kullan\u0131rken, policy ismini &#8220;resiliency.yaml&#8221; olarak tan\u0131mlamam\u0131z gerekmektedir.<\/p><\/blockquote>\n<pre>apiVersion: dapr.io\/v1alpha1\r\nkind: Resiliency\r\nmetadata:\r\n  name: myresiliency\r\nscopes:\r\n  # optionally scope the policy to specific apps\r\nspec:\r\n  policies:\r\n    timeouts:\r\n      # timeout policy definitions\r\n\r\n    retries:\r\n      # retry policy definitions\r\n\r\n    circuitBreakers:\r\n      # circuit breaker policy definitions\r\n\r\n  targets:\r\n    apps:\r\n      # apps and their applied policies here\r\n\r\n    actors:\r\n      # actor types and their applied policies here\r\n\r\n    components:\r\n      # components and their applied policies here<\/pre>\n<p>Ayr\u0131ca policy&#8217;ler tan\u0131mlarken baz\u0131 default policy&#8217;lere de g\u00f6z atmam\u0131z iyi bir fikir olacakt\u0131r. \u00d6rne\u011fin retry mekanizmas\u0131 baz\u0131 building block&#8217;lar i\u00e7in default verilerle aktif bir \u015fekilde gelmektedir ve override etmedi\u011fimiz s\u00fcrece yeni tan\u0131mlanan policy&#8217;ler ekstra olarak handle edilmektedir. Bu nedenle policy&#8217;ler ve policy hiyerar\u015fisi hakk\u0131nda ayr\u0131lt\u0131l\u0131 bilgi edinebilmek i\u00e7in <em><a href=\"https:\/\/docs.dapr.io\/operations\/resiliency\/policies\/#how-default-policies-and-built-in-retries-work-together\" target=\"_blank\" rel=\"noopener\">buraya<\/a><\/em> bakmak, faydam\u0131za olacakt\u0131r.<\/p>\n<p>\u015eimdi local ortamda test i\u015flemleri i\u00e7in her iki <em>API<\/em>&#8216;\u0131 nas\u0131l aya\u011fa kald\u0131rabiliriz bir ona bakal\u0131m.<\/p>\n<h2>Test Edelim<\/h2>\n<p>\u015eimdi <em>API<\/em>&#8216;lar\u0131 \u00e7al\u0131\u015ft\u0131rabilmek i\u00e7in terminal \u00fczerinden ilgili proje dizinlerine gidelim ve a\u015fa\u011f\u0131daki komut sat\u0131rlar\u0131n\u0131 kullanarak <em>Dapr<\/em> ile birlikte API&#8217;lar\u0131 \u00e7al\u0131\u015ft\u0131ral\u0131m.<\/p>\n<pre>dapr run --app-id shoppingcartapi --app-port 5000 -- dotnet run\r\ndapr run --app-id recommendationapi --app-port 6000 -- dotnet run<\/pre>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: &#8220;<em>dapr run<\/em>&#8221; komutu ile ilgili daha farkl\u0131 se\u00e7eneklere ise, &#8220;dapr run &#8211;help&#8221; \u00fczerinden eri\u015febilirsiniz. \u00d6rne\u011fin default <em>Dapr<\/em> gRPC ve HTTP port&#8217;lar\u0131n\u0131 de\u011fi\u015ftirebilir, veya size uygun max request ve buffer size&#8217;lar\u0131 ile ilgili de\u011fi\u015fiklikler yapabilirsiniz.<\/p><\/blockquote>\n<p><a href=\"\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6.jpg\"><img decoding=\"async\" class=\"aligncenter wp-image-4175 size-full lazyload\" data-src=\"\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6.jpg\" alt=\"\" width=\"2376\" height=\"848\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6.jpg 2376w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6-300x107.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6-1024x365.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6-768x274.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6-1536x548.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-run-api-dotnet-6-2048x731.jpg 2048w\" data-sizes=\"(max-width: 2376px) 100vw, 2376px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2376px; --smush-placeholder-aspect-ratio: 2376\/848;\" \/><\/a><\/p>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi <em>Dapr<\/em>, <strong>DaprShop.ShoppingCart.API <\/strong>&#8216;\u0131n\u0131 port 5000 ve <strong>DaprShop.Recommendation.API<\/strong> &#8216;\u0131n\u0131 da port 6000 \u00fczerinden aya\u011fa kald\u0131rd\u0131.<\/p>\n<p>\u015eimdi <strong>DaprShop.ShoppingCart.API <\/strong>&#8216;\u0131n\u0131n <em>Swagger UI<\/em>&#8216;\u0131na eri\u015felim ve sepet&#8217;e bir adet \u00fcr\u00fcn ekleyelim veya a\u015fa\u011f\u0131daki <em>cURL<\/em> komutunu \u00e7al\u0131\u015ft\u0131ral\u0131m.<\/p>\n<pre>curl -X 'POST' \\\r\n  'http:\/\/localhost:5000\/api\/shopping-cart\/123456\/items' \\\r\n  -H 'accept: text\/plain' \\\r\n  -H 'Content-Type: application\/json' \\\r\n  -d '{\r\n  \"productId\": \"1\",\r\n  \"productName\": \"Samsung Z Fold 4\",\r\n  \"price\": 1500,\r\n  \"quantity\": 1\r\n}'<\/pre>\n<p>\u00dcr\u00fcn\u00fc sepet&#8217;e eklemenin ard\u0131ndan a\u015fa\u011f\u0131daki gibi <strong>DaprShop.Recommendation.API<\/strong> terminal ekran\u0131 \u00fczerinden de g\u00f6rebilece\u011fimiz \u00fczere, ilgili event belirtmi\u015f oldu\u011fumuz topic \u00fczerinden consume edilmi\u015ftir.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2022\/10\/dapr-event-consume.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4177 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/10\/dapr-event-consume.jpg\" alt=\"\" width=\"2376\" height=\"584\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-event-consume.jpg 2376w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-event-consume-300x74.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-event-consume-1024x252.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-event-consume-768x189.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-event-consume-1536x378.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-event-consume-2048x503.jpg 2048w\" data-sizes=\"(max-width: 2376px) 100vw, 2376px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2376px; --smush-placeholder-aspect-ratio: 2376\/584;\" \/><\/a><\/p>\n<p>Ayr\u0131ca state-store \u00fczerinde olu\u015fturmu\u015f oldu\u011fumuz sepet bilgisine de, <strong>DaprShop.ShoppingCart.API <\/strong>&#8216;\u0131 \u00fczerinden a\u015fa\u011f\u0131daki gibi eri\u015fim sa\u011flayabiliriz.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2022\/10\/dapr-statestore-dotnet-6.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4178 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/10\/dapr-statestore-dotnet-6.jpg\" alt=\"\" width=\"1966\" height=\"1084\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-statestore-dotnet-6.jpg 1966w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-statestore-dotnet-6-300x165.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-statestore-dotnet-6-1024x565.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-statestore-dotnet-6-768x423.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-statestore-dotnet-6-1536x847.jpg 1536w\" data-sizes=\"(max-width: 1966px) 100vw, 1966px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1966px; --smush-placeholder-aspect-ratio: 1966\/1084;\" \/><\/a><\/p>\n<h2>Dapr Dashboard<\/h2>\n<p>Ayr\u0131ca sahip oldu\u011fumuz component&#8217;ler, deploy etmi\u015f oldu\u011fumuz uygulamalar ve onlar\u0131n configuration&#8217;lar\u0131 hakk\u0131ndaki bilgilere, <em>Dapr Dashboard<\/em> \u00fczerinden kolayca ula\u015fabiliriz.<\/p>\n<p>Bunun i\u00e7in tek yapmam\u0131z gereken, &#8220;<em>dapr dashboard<\/em>&#8221; komutunu \u00e7al\u0131\u015ft\u0131rmak. Ard\u0131ndan port <strong>8080<\/strong> \u00fczerinden a\u015fa\u011f\u0131daki gibi eri\u015fim sa\u011flayabiliriz.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2022\/10\/dapr-dashboard.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4179 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/10\/dapr-dashboard.jpg\" alt=\"\" width=\"2058\" height=\"994\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dashboard.jpg 2058w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dashboard-300x145.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dashboard-1024x495.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dashboard-768x371.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dashboard-1536x742.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dashboard-2048x989.jpg 2048w\" data-sizes=\"(max-width: 2058px) 100vw, 2058px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2058px; --smush-placeholder-aspect-ratio: 2058\/994;\" \/><\/a><\/p>\n<h2>Dapr Observability<\/h2>\n<p>Bildi\u011fimiz gibi observability production ortamlar\u0131 i\u00e7in olduk\u00e7a kritik bir konu. \u00d6zellikle microservice&#8217;ler ile \u00e7al\u0131\u015f\u0131yorsak, baz\u0131 sorunlar\u0131 kolayca anlayabilmemiz ve tespit edebilmemiz ad\u0131na development ortamlar\u0131 i\u00e7in de \u00f6nemli bir konu oldu\u011funu s\u00f6yleyebilirim. Bu konuda genellikle uygulamalar\u0131m\u0131zdan farkl\u0131 metrikleri toplayabilmek ad\u0131na, uygulama \u00f6zelinde \u00e7e\u015fitli <em>SDK<\/em>&#8216;ler kullan\u0131p, configuraton&#8217;lar ger\u00e7ekle\u015ftiriyoruz.<\/p>\n<p>Neyseki<em> Dapr<\/em>&#8216;\u0131n observability i\u00e7in de bir building block&#8217;a sahip oldu\u011funu s\u00f6ylemi\u015ftik. <em>Dapr<\/em> sidecar&#8217;\u0131 default olarak trafi\u011fi intercept ederek <strong>tracing<\/strong>, <strong>logs<\/strong>, <strong>health <\/strong>ve\u00a0<strong>metrics<\/strong> gibi \u00e7e\u015fitli verileri extract etmektedir. Ayr\u0131ca \u00e7e\u015fitli observability tool&#8217;lar\u0131 ile de entegre edebilmekteyiz.<\/p>\n<p><em>Dapr<\/em>, event&#8217;ler i\u00e7in <em>CloudEvents<\/em> standart format\u0131n\u0131 destekledi\u011fi gibi, telemetry verileri i\u00e7in de <strong><em>OpenTelemetry<\/em> <\/strong>ve <strong><em>Zipkin<\/em><\/strong>&#8216;i desteklemektedir. <em>Zipkin<\/em> deste\u011fi ise default olarak gelmektedir. Ayr\u0131ca tracing context olu\u015fturma ve yayma i\u015flemini de otomatik olarak ger\u00e7ekle\u015ftirmektedir.<\/p>\n<p>K\u0131sacas\u0131 tracing verilerine default olarak a\u015fa\u011f\u0131daki gibi <em>Zipkin UI<\/em>&#8216;\u0131 \u00fczerinden eri\u015fim sa\u011flayabiliriz.<\/p>\n<pre>http:\/\/localhost:9411<\/pre>\n<p><a href=\"\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4180 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr.jpg\" alt=\"\" width=\"2184\" height=\"1210\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr.jpg 2184w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr-300x166.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr-1024x567.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr-768x425.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr-1536x851.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/zipkin-ui-dapr-2048x1135.jpg 2048w\" data-sizes=\"(max-width: 2184px) 100vw, 2184px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2184px; --smush-placeholder-aspect-ratio: 2184\/1210;\" \/><\/a><\/p>\n<p>Ayr\u0131ca <em>Dapr<\/em>, <em><strong>Prometheus<\/strong><\/em>&#8216;u metrik standart\u0131 olarak kullan\u0131r ve performans ve kaynak t\u00fcketimi gibi metrikleri sa\u011flar.<\/p>\n<h2>Toparlayal\u0131m<\/h2>\n<p><em>Dapr<\/em> ilk duyuruldu\u011fu g\u00fcnden bu yana hep akl\u0131mda ve ilgi alanlar\u0131m aras\u0131nda yer ald\u0131. Bir s\u00fcredir <em>Dapr<\/em> kullanarak bir ka\u00e7 uygulama geli\u015ftiriyorum ve sunmu\u015f oldu\u011fu farkl\u0131 building block&#8217;lar\u0131 kullan\u0131rken olduk\u00e7a keyif al\u0131yorum. Bir developer olarak uygulama geli\u015ftirme s\u00fcrecinde, ilk ba\u015fta herhangi bir teknoloji veya baz\u0131 library&#8217;ler hakk\u0131nda d\u00fc\u015f\u00fcnmeden \u00e7al\u0131\u015fabilmek, h\u0131zl\u0131 ve efektif bir deneyim. Ayr\u0131ca resiliency veya observability endi\u015feleri olmadan yaln\u0131zca business fonksiyonalitelerine odaklanabilmemiz de art\u0131 taraf\u0131.<\/p>\n<p>Ayr\u0131ca farkl\u0131 business use-case&#8217;leri i\u00e7in farkl\u0131 building block&#8217;lar sa\u011flaman\u0131n yan\u0131nda, iyi bir abstraction&#8217;a da sahip olmas\u0131 nedeniyle microservice&#8217;lerimizin <strong>loosely coupled<\/strong> olarak geli\u015ftirilebilmesine de katk\u0131 sa\u011flamaktad\u0131r.<\/p>\n<p>Bir sonraki seri de ise default component&#8217;ler yerine\u00a0farkl\u0131 <em>Azure<\/em> service&#8217;lerini kullanarak, geli\u015ftirmi\u015f oldu\u011fumuz <em>API<\/em>&#8216;lar\u0131 <em>Azure Container Apps<\/em>&#8216;e nas\u0131l deploy edebilece\u011fiz konusuna bir bakaca\u011f\u0131z.<\/p>\n<h2>Referanslar<\/h2>\n<blockquote><p><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/architecture\/dapr-for-net-developers?WT.mc_id=DT-MVP-5003382\"><em>https:\/\/learn.microsoft.com\/en-us\/dotnet\/architecture\/dapr-for-net-developers\/<\/em><\/a><br \/>\n<a href=\"https:\/\/docs.dapr.io\/concepts\/overview\/\" target=\"_blank\" rel=\"noopener\"><em>https:\/\/docs.dapr.io\/concepts\/overview\/<\/em><\/a><\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Bildi\u011fimiz gibi her ge\u00e7en g\u00fcn teknoloji ve al\u0131\u015fkanl\u0131klar\u0131m\u0131z s\u00fcrekli de\u011fi\u015fmekte. \u00d6zellikle pandemi s\u00fcrecinden sonra dijitalle\u015fmeye ve teknolojiye olan e\u011filim olduk\u00e7a artm\u0131\u015f durumda. Durum b\u00f6yleyken bizlerde geli\u015ftiriciler olarak bu de\u011fi\u015fimlere ve isteklere adapte olabilmek ad\u0131na, geli\u015ftirdi\u011fimiz uygulamalar\u0131n m\u00fcmk\u00fcn olabildi\u011fince portable ve scalable yap\u0131da olmalar\u0131na dikkat etmekteyiz.&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">Dapr ve .NET Kullanarak Minimum Efor ile Microservice&#8217;ler Geli\u015ftirmek &#8211; 01<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":4206,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,505,68,48,418,434,457,285,368],"tags":[635,538,649,650,651,259,520],"class_list":["post-4143","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-net-core","category-architectural","category-asp-net-web-api","category-azure","category-containerizing","category-dotnet","category-messaging","category-microservices","tag-net-6","tag-cloud-native","tag-dapr","tag-event-driven","tag-loosely-coupling","tag-microservice","tag-resiliency","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":true,"content":true,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Dapr ve .NET Kullanarak Minimum Efor ile Microservice&#039;ler Geli\u015ftirmek - 01 - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Dapr ve .NET Kullanarak Minimum Efor ile Microservice&#039;ler Geli\u015ftirmek - 01 - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2022-10-29T18:17:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-10-30T12:13:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dotnet-01-gokhan-gokalp-com.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"35 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\"Dapr ve .NET Kullanarak Minimum Efor ile Microservice&#8217;ler Geli\u015ftirmek &#8211; 01\",\"datePublished\":\"2022-10-29T18:17:19+00:00\",\"dateModified\":\"2022-10-30T12:13:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/\"},\"wordCount\":5751,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/dapr-dotnet-01-gokhan-gokalp-com.jpg\",\"keywords\":[\".net 6\",\"cloud native\",\"dapr\",\"event driven\",\"loosely coupling\",\"MicroService\",\"resiliency\"],\"articleSection\":[\".NET\",\".NET Core\",\"Architectural\",\"Asp.Net Web API\",\"Azure\",\"Containerizing\",\"dotnet\",\"Messaging\",\"Microservices\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/\",\"name\":\"Dapr ve .NET Kullanarak Minimum Efor ile Microservice'ler Geli\u015ftirmek - 01 - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/dapr-dotnet-01-gokhan-gokalp-com.jpg\",\"datePublished\":\"2022-10-29T18:17:19+00:00\",\"dateModified\":\"2022-10-30T12:13:09+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#primaryimage\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/dapr-dotnet-01-gokhan-gokalp-com.jpg\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/10\\\/dapr-dotnet-01-gokhan-gokalp-com.jpg\",\"width\":1200,\"height\":675},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building Microservices by Using Dapr and .NET with Minimum Effort &#8211; 01\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Dapr ve .NET Kullanarak Minimum Efor ile Microservice'ler Geli\u015ftirmek - 01 - G\u00f6khan G\u00f6kalp","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/","og_locale":"tr_TR","og_type":"article","og_title":"Dapr ve .NET Kullanarak Minimum Efor ile Microservice'ler Geli\u015ftirmek - 01 - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2022-10-29T18:17:19+00:00","article_modified_time":"2022-10-30T12:13:09+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dotnet-01-gokhan-gokalp-com.jpg","type":"image\/jpeg"}],"author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"35 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":"Dapr ve .NET Kullanarak Minimum Efor ile Microservice&#8217;ler Geli\u015ftirmek &#8211; 01","datePublished":"2022-10-29T18:17:19+00:00","dateModified":"2022-10-30T12:13:09+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/"},"wordCount":5751,"commentCount":6,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dotnet-01-gokhan-gokalp-com.jpg","keywords":[".net 6","cloud native","dapr","event driven","loosely coupling","MicroService","resiliency"],"articleSection":[".NET",".NET Core","Architectural","Asp.Net Web API","Azure","Containerizing","dotnet","Messaging","Microservices"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/","url":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/","name":"Dapr ve .NET Kullanarak Minimum Efor ile Microservice'ler Geli\u015ftirmek - 01 - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#primaryimage"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dotnet-01-gokhan-gokalp-com.jpg","datePublished":"2022-10-29T18:17:19+00:00","dateModified":"2022-10-30T12:13:09+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#primaryimage","url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dotnet-01-gokhan-gokalp-com.jpg","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/10\/dapr-dotnet-01-gokhan-gokalp-com.jpg","width":1200,"height":675},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/building-microservices-by-using-dapr-and-net-with-minimum-effort-01\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Building Microservices by Using Dapr and .NET with Minimum Effort &#8211; 01"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1777985325"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/4143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=4143"}],"version-history":[{"count":6,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/4143\/revisions"}],"predecessor-version":[{"id":4303,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/4143\/revisions\/4303"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media\/4206"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=4143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=4143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=4143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}