﻿
{"id":18501,"date":"2020-10-24T10:07:17","date_gmt":"2020-10-24T10:07:17","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=18501"},"modified":"2020-10-24T10:07:17","modified_gmt":"2020-10-24T10:07:17","slug":"asp-net-core-etag-nedir-etag-ile-response-caching-islemi-nasil-gerceklestirilir","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-etag-nedir-etag-ile-response-caching-islemi-nasil-gerceklestirilir\/","title":{"rendered":"Asp.NET Core &#8211; ETag Nedir? ETag \u0130le Response Caching \u0130\u015flemi Nas\u0131l Ger\u00e7ekle\u015ftirilir?"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde client ile server aras\u0131ndaki ili\u015fkiyi daha performansl\u0131 ve server&#8217;da ki i\u015f y\u00fck\u00fcn\u00fc daha az maliyetli hale getirmek i\u00e7in d\u00fc\u015f\u00fcn\u00fclm\u00fc\u015f olan ve HTTP response&#8217;unda client&#8217;a g\u00f6nderilen bir bilgi olarak kar\u015f\u0131m\u0131za \u00e7\u0131kan <em>ETag<\/em> \u00fczerine detayl\u0131ca konu\u015fuyor olacak ve ilgili konunun ne oldu\u011funu, i\u015flevsel a\u00e7\u0131dan nelere yarad\u0131\u011f\u0131n\u0131, \u00f6nbellekleme a\u00e7\u0131s\u0131ndan ne tarz ama\u00e7larla kullan\u0131ld\u0131\u011f\u0131n\u0131 ve biz yaz\u0131l\u0131m geli\u015ftiricileri olarak bu bilgiyi lehimize ne \u015fekilde ve nas\u0131l kullanabilece\u011fimizi inceleyecek ve irdeleyece\u011fiz. Buyrun, hi\u00e7 vakit kaybetmeden konumuzu detayland\u0131ral\u0131m&#8230;<\/p>\n<h3 style=\"color:#e83e8c;\">ETag Nedir?<\/h3>\n<blockquote style=\"color:purple;\"><p><em>ETag; Entity Tag &#8211; Varl\u0131k Etiketi<\/em><\/p><\/blockquote>\n<p>ETag, client taraf\u0131ndan yap\u0131lan istek neticesinde \u00fcretilen datan\u0131n g\u00fcncellik durumunu ifade etmek ve client&#8217;\u0131 bilgilendirmek i\u00e7in server taraf\u0131ndan \u00fcretilen ve HTTP response&#8217;unda ta\u015f\u0131nan bir bilgidir.<\/p>\n<p>Genellikle web sunucular, i\u00e7eri\u011fini statik olarak kabul ettikleri dosyalar<span style=\"font-size:11px;\">(.js, .html, .jpg, .png vs.)<\/span> i\u00e7in ETag&#8217;i otomatik \u00fcretmekte ve HTTP response&#8217;lar\u0131nda g\u00f6ndermektedirler. Bu duruma s\u00f6zgelimi olarak bu blog&#8217;ta ki<span style=\"font-size:11px;\">(gencayyildiz.com\/blog)<\/span> herhangi bir g\u00f6rseli elle alabilir ve response header&#8217;\u0131n\u0131 inceleyebiliriz.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir..jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir..jpg\" alt=\"Asp.NET Core - ETag Nedir? ETag \u0130le Response Caching \u0130\u015flemi Nas\u0131l Ger\u00e7ekle\u015ftirilir?\" width=\"659\" height=\"478\" class=\"aligncenter size-full wp-image-18511\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir..jpg 659w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-300x218.jpg 300w\" sizes=\"auto, (max-width: 659px) 100vw, 659px\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere sayfaya y\u00fcklenen herhangi bir g\u00f6rsel(.jpg) sunucu taraf\u0131ndan &#8216;etag&#8217; bilgisiyle g\u00f6nderilmi\u015ftir. Bu bilgi yukar\u0131da bahsedildi\u011fi gibi sunucu taraf\u0131ndan otomatik olu\u015fturulmaktad\u0131r.<\/p>\n<p>Evet&#8230; ETag&#8217;\u0131n sunucu taraf\u0131ndan olu\u015fturuldu\u011funu ve hatta sunucu taraf\u0131nda statik kabul edilen dosyalar i\u00e7in otomatik olu\u015fturuldu\u011funu \u00f6\u011frenmi\u015f olduk. \u015eimdi as\u0131l sorular\u0131m\u0131za gelelim. Neden olu\u015fturuldu\u011funa ve nas\u0131l kullan\u0131ld\u0131\u011f\u0131na?<\/p>\n<h3 style=\"color:#e83e8c;\">ETag Neden Olu\u015fturulur?<\/h3>\n<p>ETag, client&#8217;\u0131n server&#8217;a yapt\u0131\u011f\u0131 istek neticesinde gelecek olan datan\u0131n g\u00fcncel olup olmama durumunu bizlere bildirmek i\u00e7in kullan\u0131lan bir de\u011ferdir. Neden mi? \u00c7\u00fcnk\u00fc genellikle server&#8217;da \u00fcretilen datalar, sonraki isteklerde performans\u0131 artt\u0131rmak ve maliyeti d\u00fc\u015f\u00fcrmek amac\u0131yla \u00f6nbelleklenmekte(caching) ve ilk istekten sonrakilerde bu \u00f6nbellekteki datalar client&#8217;a g\u00f6nderilmektedir.<\/p>\n<p>Bu \u00f6nbellekleme sonras\u0131 s\u00fcre\u00e7lerde bu datalar\u0131n s\u0131k s\u0131k yenilenmesi yahut g\u00fcncellenmesi gibi olduk\u00e7a do\u011fal fiziksel durumlar s\u00f6z konusu olabilir. \u0130\u015fte bu durumlarda g\u00fcncellemelerden client&#8217;\u0131n haberi olmayaca\u011f\u0131ndan ve \u00f6nbelle\u011fe al\u0131nm\u0131\u015f verinin ne zaman yenilenece\u011fini veya de\u011fi\u015fece\u011fini bilemeyece\u011finden dolay\u0131 her request&#8217;e kar\u015f\u0131l\u0131k \u00f6nbellekteki verilerin taa ki \u00f6nbellekleme s\u00fcresi sona erinceye kadar birebir ayn\u0131 \u015fekilde gelmesi s\u00f6z konusu olacakt\u0131r. Bu \u015fekilde \u00f6nbelleklenmi\u015f datalar ile API&#8217;dan gelecek olan datalar\u0131n s\u00fcrekli ayn\u0131 olmas\u0131, client ile server aras\u0131ndaki veri ak\u0131\u015f\u0131nda l\u00fczumsuz bir trafi\u011fe sebep olacak ve s\u00fcreci olumsuz etkileyecektir. Burada ideal olan, client taraf\u0131ndan yap\u0131lan istek neticesinde g\u00f6nderilecek datan\u0131n \u00f6nceden \u00f6nbelleklenmi\u015f datadan farkl\u0131 olmas\u0131 kayd\u0131yla API&#8217;dan g\u00f6nderilmesini sa\u011flamak, aksi taktirde zaten var olan datan\u0131n tekrar g\u00f6nderilmeksizin kullan\u0131m\u0131na devam edilmesini client&#8217;a bildirmektir.<\/p>\n<p>Burada misal olarak bir \u015firketteki yap\u0131lan sat\u0131\u015flar\u0131n liste olarak getirildi\u011fi herhangi bir uygulaman\u0131n senaryosunu d\u00fc\u015f\u00fcnelim. Uygulaman\u0131n yap\u0131lan her istek neticesinde sat\u0131\u015flar\u0131 daha h\u0131zl\u0131 listeleyebilmek i\u00e7in bu datalar\u0131 \u00f6nbelle\u011fe ald\u0131\u011f\u0131n\u0131 varsayal\u0131m. \u00d6nbellekleme i\u015fleminin s\u00fcresi dolana kadar yap\u0131lan t\u00fcm isteklerde uygulamaya datalar \u00f6nbellek \u00fczerinden gitmekte, s\u00fcre bittikten sonraki ilk istekte ise tekrar veritaban\u0131ndan \u00e7ekilip \u00f6nbelleklenmektedir. \u0130\u015fte burada kritik yapmaya de\u011fer iki durum s\u00f6z konusu olmaktad\u0131r.<\/p>\n<p><strong>Birinci durum<\/strong>; <em>\u00d6nbellekleme s\u00fcresi i\u00e7erisinde datalar ya de\u011fi\u015ftiyse\/g\u00fcncellendiyse?<\/em><br \/>\n\u00d6nbellekleme s\u00fcresi i\u00e7erisinde datalar fiziksel olarak de\u011fi\u015fti yahut g\u00fcncellendiyse e\u011fer uygulama hala \u00f6nbellekteki datalarla \u00e7al\u0131\u015famaya devam edecektir. Bu durum eksik verilerle \u00e7al\u0131\u015fmay\u0131 gerektirece\u011finden dolay\u0131 tutars\u0131z sonu\u00e7lara ve yanl\u0131\u015f hesaplamalara sebep olacakt\u0131r. Yani amiyane tabirle bir handikapt\u0131r. Burada g\u00fcncel verilerin tekrar veritaban\u0131ndan \u00e7ekilmesi ve client&#8217;a g\u00f6nderilmesi gerekmektedir.<\/p>\n<p><strong>\u0130kinci durum<\/strong>; <em>\u00d6nbellekleme s\u00fcrecinden sonraki datalar ya hen\u00fcz de\u011fi\u015fmediyse\/g\u00fcncellenmediyse?<\/em><br \/>\n\u00d6nbellekleme s\u00fcresi bitti\u011fi taktirde datalar yeniden veritaban\u0131ndan \u00e7ekilecektir. Haliyle herhangi bir fiziksel de\u011fi\u015fiklik yahut g\u00fcncelleme olmamas\u0131 durumunda \u00e7ekilen bu datalar\u0131n client taraf\u0131na g\u00f6nderilmesi tekrardan l\u00fczumsuz bir maliyete sebep olacakt\u0131r. Burada da elde edilen data ile client&#8217;ta ki aras\u0131nda farkl\u0131l\u0131k varsa e\u011fer g\u00f6nderilmesi, aksi taktirde client&#8217;a elindekiyle yetinmesi bildirilmelidir.<\/p>\n<p>\u0130\u015fte t\u00fcm bu s\u00fcre\u00e7lerde server taraf\u0131nda \u00fcretilen ETag de\u011feri, datan\u0131n g\u00fcncel olup olmama durumuna istinaden client \u00fczerinden server&#8217;\u0131 bilgilendirmek i\u00e7in kullan\u0131lan bir de\u011ferdir.<\/p>\n<h3 style=\"color:#e83e8c;\">ETag Nas\u0131l \u00c7al\u0131\u015f\u0131r?<\/h3>\n<p>ETag; sunucu taraf\u0131nda \u00fcretilen datan\u0131n, client&#8217;taki mevcut data ile aralar\u0131nda olan fark\u0131 ortaya koyabilmek i\u00e7in, ilgili dataya sunucu taraf\u0131ndan bir versiyon\/s\u00fcr\u00fcm bilgisi \u00fcretilmesi ve client&#8217;dan gelen isteklerde bu versiyon\/s\u00fcr\u00fcm bilgisini alarak yeni \u00fcretilen yahut \u00f6nbellekten \u00e7ekilen datan\u0131n versiyon\/s\u00fcr\u00fcm bilgisiyle k\u0131yaslanarak g\u00fcncellik durumuna istinaden client&#8217;\u0131n bilgilendirilmesi esas\u0131na dayanan bir mant\u0131\u011fa sahip etikettir. <\/p>\n<blockquote style=\"color:purple;\"><p><em>ETag&#8217;da ama\u00e7; API taraf\u0131ndan client&#8217;ta var olan verinin l\u00fczumsuz yere tekrar g\u00f6nderilmesini engellemek ve b\u00f6ylece client&#8217;\u0131n cache(\u00f6nbellek)teki veriyi kullanmas\u0131na devam etmesini sa\u011flamakt\u0131r.<\/em><\/p><\/blockquote>\n<p>Bu versiyon\/s\u00fcr\u00fcm istek neticesinde ge\u00e7erlili\u011fini yitirmi\u015fse datalar g\u00fcncellenmi\u015f yahut de\u011fi\u015ftirilmi\u015f demektir. Bu durumda da ilgili datalar yeni bir versiyon\/s\u00fcr\u00fcm bilgisiyle tekrar \u00fcretilerek client&#8217;a g\u00f6nderilmelidir.<\/p>\n<p>\u0130\u015fte burada bahsedilen versiyon\/s\u00fcr\u00fcm esas\u0131nda ETag de\u011feridir.<\/p>\n<h3 style=\"color:#e83e8c;\">Client \u0130le Server Aras\u0131nda ETag \u0130\u015flevi<\/h3>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-1.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-1-300x227.jpg\" alt=\"Asp.NET Core - ETag Nedir? ETag \u0130le Response Caching \u0130\u015flemi Nas\u0131l Ger\u00e7ekle\u015ftirilir?\" width=\"300\" height=\"227\" class=\"alignleft size-medium wp-image-18557\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-1-300x227.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-1-768x582.jpg 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-1.jpg 784w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>ETag, basit\u00e7e bir dizeden ibaret de\u011ferdir. Bu de\u011fer, client&#8217;\u0131n sahip oldu\u011fu verilerin s\u00fcr\u00fcm bilgisini temsil eder ve client bu s\u00fcr\u00fcm bilgisini sunucuda herhangi bir yeni s\u00fcr\u00fcm\u00fcn olu\u015fturulup olu\u015fturulmad\u0131\u011f\u0131n\u0131 kontrol etmek i\u00e7in kullan\u0131r. Sunucu, client taraf\u0131nda bulunan s\u00fcr\u00fcmden farkl\u0131 yeni bir s\u00fcr\u00fcm de\u011ferine sahip ba\u015fka bir veri \u00fcretiyorsa e\u011fer bunu client&#8217;a yeni s\u00fcr\u00fcm kodu e\u015fli\u011finde &#8216;200 Status Code&#8217;u ile iletecektir. Aksi taktirde client&#8217;ta ki s\u00fcr\u00fcmden farkl\u0131 bir s\u00fcr\u00fcmde veri \u00fcretilmiyorsa &#8216;304 Status Code&#8217; de\u011feri ile yan\u0131t verecektir.<\/p>\n<p>Sunucudan gelen ETag de\u011ferini client, request header&#8217;\u0131n &#8216;If-None-Match&#8217; parametresiyle tekrar sunucuya iletir. Sunucu, istemciden gelen bu parametreyle o anda ki veriler i\u00e7in \u00fcretilen ETag de\u011ferini kar\u015f\u0131la\u015ft\u0131r\u0131r. Bu kar\u015f\u0131la\u015ft\u0131rma neticesinde bir de\u011fi\u015fiklik yoksa verilerin de\u011fi\u015fmedi\u011fi ve client&#8217;\u0131n local storage&#8217;\u0131n\u0131n g\u00fcncellenmesinin gerekmedi\u011fi anla\u015f\u0131lacak ve 304(Not Modified) durum koduyla bunu client&#8217;a bildirecektir. Bu d\u00f6ng\u00fc, sunucu taraf\u0131nda kaynak de\u011fi\u015fene kadar devam edecektir.<\/p>\n<p><strong>Peki sunucu ETag de\u011ferini nas\u0131l \u00fcretir?<\/strong><br \/>\nT\u00fcm bu s\u00fcre\u00e7te client&#8217;\u0131n ETag olarak kabul etti\u011fi dizge hakk\u0131nda hi\u00e7bir fikri yoktur ve JWT gibi \u00f6zel bir \u00e7\u00f6z\u00fcmleyici gerektirmedi\u011fi i\u00e7in sunucu taraf\u0131ndan bu ETag her t\u00fcrl\u00fc mekanizma yahut algoritma ile \u00fcretilebilir.<\/p>\n<h3 style=\"color:#e83e8c;\">Asp.NET Core API \u0130le Basit Bir ETag Uygulamas\u0131<\/h3>\n<p>Asp.NET Core uygulamalar\u0131nda client&#8217;tan gelen iste\u011fe g\u00f6re ETag kontrol\u00fc ger\u00e7ekle\u015ftirmek istiyorsan\u0131z e\u011fer a\u015fa\u011f\u0131daki gibi bir attribute tasarlaman\u0131z olduk\u00e7a elveri\u015fli olacakt\u0131r. (Attribute d\u0131\u015f\u0131nda middleware gibi \u00e7\u00f6z\u00fcmlere de ba\u015fvurabilirsiniz. Lakin konuya dair en efektif \u00e7\u00f6z\u00fcm\u00fcn attribute oldu\u011fu kanaatindeyim&#8230;)<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]\r\n    public class ETagFilterAttribute : ActionFilterAttribute\r\n    {\r\n        \/\/\u0130stek neticesinde ilgili Action tetiklendikten sonra bu metot tetiklenir.\r\n        public override void OnActionExecuted(ActionExecutedContext context)\r\n        {\r\n            \/\/Gelen iste\u011fin GET ve tetiklenen Action metodun sonucunun 200 oldu\u011funda;\r\n            if (context.HttpContext.Request.Method == &quot;GET&quot; &amp;&amp; context.HttpContext.Response.StatusCode == (int)HttpStatusCode.OK)\r\n            {\r\n                \/\/context.Result -&gt; Tetiklenen Action metodun neticesinde \u00fcretilen geriye d\u00f6nd\u00fcr\u00fclecek\r\n                \/\/olan de\u011feri ifade etmektedir. JsonConvert.SerializeObject metodu ile(Newtonsoft)\r\n                \/\/bu de\u011fer serilize edilerek string vaziyette elde edilmektedir.\r\n                string resultData = JsonConvert.SerializeObject(context.Result);\r\n\r\n                \/\/Yukar\u0131daki resultData kullan\u0131larak bir ETag \u00fcretiliyor. Bu ETag de\u011feri, resultData de\u011ferine g\u00f6re tekil \u00fcretilecektir. Dolay\u0131s\u0131yla ilgili action'a gelen t\u00fcm isteklerde resultData ayn\u0131 olduk\u00e7a her seferinde ayn\u0131 de\u011fer \u00fcretilecektir.\r\n                string etag = ETagGenerator.GetETag(context.HttpContext.Request.Path.ToString(), Encoding.UTF8.GetBytes(resultData));\r\n\r\n                \/\/Gelen istek header'\u0131nda 'IfNoneMatch' parametresi var m\u0131? kontrol ediliyor;\r\n                if (context.HttpContext.Request.Headers.Keys.Contains(HeaderNames.IfNoneMatch))\r\n                {\r\n                    \/\/Header'dan 'IfNoneMatch' de\u011feri al\u0131n\u0131yor.\r\n                    string inComingETag = context.HttpContext.Request.Headers&#x5B;HeaderNames.IfNoneMatch].ToString();\r\n\r\n                    \/\/\u00dcretilen ETag ile header'dan gelen e\u015fle\u015ftiriliyor;\r\n                    if (inComingETag.Equals(etag))\r\n                        \/\/E\u011fer ayn\u0131 ise geriye 304 Status Code de\u011feri d\u00f6nd\u00fcr\u00fcl\u00fcyor.\r\n                        context.Result = new StatusCodeResult((int)HttpStatusCode.NotModified);\r\n                }\r\n                \/\/\u00dcretilen ETag de\u011feri response header'\u0131na ETag parametresi kar\u015f\u0131l\u0131\u011f\u0131nda yerle\u015ftiriliyor.\r\n                context.HttpContext.Response.Headers.Add(HeaderNames.ETag, new&#x5B;] { etag });\r\n            }\r\n\r\n            base.OnActionExecuted(context);\r\n        }\r\n    }\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere ilgili attribute&#8217;un i\u015flevsel a\u00e7\u0131dan gerekli t\u00fcm a\u00e7\u0131klamalar\u0131 sat\u0131r aral\u0131klar\u0131nda belirtilmi\u015f vaziyettedir. Burada ETag \u00fcretiminden sorumlu &#8216;ETagGenerator&#8217; s\u0131n\u0131f\u0131n\u0131n i\u00e7eri\u011fini de a\u015fa\u011f\u0131ya alal\u0131m;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    static public class ETagGenerator\r\n    {\r\n        \/\/Rastgele binary kombin olu\u015fturuyoruz.\r\n        private static byte&#x5B;] Combine(byte&#x5B;] a, byte&#x5B;] b)\r\n        {\r\n            byte&#x5B;] c = new byte&#x5B;a.Length + b.Length];\r\n            Buffer.BlockCopy(a, 0, c, 0, a.Length);\r\n            Buffer.BlockCopy(b, 0, c, a.Length, b.Length);\r\n            return c;\r\n        }\r\n        \/\/Binary de\u011ferden hashlenmi\u015f de\u011fer \u00fcretiyoruz.\r\n        private static string GenerateETag(byte&#x5B;] data)\r\n        {\r\n            using MD5 md5 = MD5.Create();\r\n            byte&#x5B;] hash = md5.ComputeHash(data);\r\n            string hex = BitConverter.ToString(hash);\r\n            return hex.Replace(&quot;-&quot;, &quot;&quot;);\r\n        }\r\n        public static string GetETag(string key, byte&#x5B;] contentBytes)\r\n        {\r\n            byte&#x5B;] keyBytes = Encoding.UTF8.GetBytes(key);\r\n            var combinedBytes = Combine(keyBytes, contentBytes);\r\n            return GenerateETag(combinedBytes);\r\n        }\r\n    }\r\n<\/pre>\n<p>\u015eimdi ilgili attribute&#8217;u kullanarak ETag kontrol\u00fc yapaca\u011f\u0131m\u0131z controller ve action&#8217;\u0131 geli\u015ftirelim. <\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    &#x5B;ApiController]\r\n    public class OrdersController : ControllerBase\r\n    {\r\n        &#x5B;ETagFilter]\r\n        public IActionResult Get()\r\n        {\r\n            return Ok(OrderList.Orders);\r\n        }\r\n    }\r\n<\/pre>\n<p>\u0130\u015fte bu kadar \ud83d\ude42 Dikkat ederseniz &#8216;OrdersController&#8217; isimli controller s\u0131n\u0131f\u0131ndaki &#8216;Get&#8217; fonksiyonu geriye kayna\u011f\u0131 bizler i\u00e7in \u00f6nemli olmayan bir order listesi d\u00f6nd\u00fcrmektedir. \u015eimdi gelin bu yap\u0131lanmay\u0131 test edelim&#8230;<\/p>\n<table>\n<tr>\n<td style=\"width:40%;\"><em>\u0130lk request<\/em><\/td>\n<td><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-2.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-2-300x124.jpg\" alt=\"Asp.NET Core - ETag Nedir? ETag \u0130le Response Caching \u0130\u015flemi Nas\u0131l Ger\u00e7ekle\u015ftirilir?\" width=\"300\" height=\"124\" class=\"aligncenter size-medium wp-image-18559\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-2-300x124.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-2.jpg 735w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nAPI&#8217;a yap\u0131lan istek neticesinde, response header&#8217;\u0131nda ETag de\u011feri d\u00f6nd\u00fcrmektedir.\n<\/td>\n<\/tr>\n<tr>\n<td><em>If-None-Match de\u011feri ile birlikte request<\/em><\/td>\n<td>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-3.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-3-300x125.jpg\" alt=\"Asp.NET Core - ETag Nedir? ETag \u0130le Response Caching \u0130\u015flemi Nas\u0131l Ger\u00e7ekle\u015ftirilir?\" width=\"300\" height=\"125\" class=\"aligncenter size-medium wp-image-18561\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-3-300x125.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-3.jpg 734w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\n\u0130kinci request&#8217;te, ilk request&#8217;te elde edilen ETag de\u011ferini &#8216;If-None-Match&#8217; header&#8217;\u0131na parametre olarak verip ger\u00e7ekle\u015ftiriyoruz. Status Code de\u011feri 304(Not Modified) d\u00f6nerek sunucuda ilgili de\u011ferin de\u011fi\u015fmedi\u011fini, client&#8217;\u0131n var olan bellekteki datayla i\u015flem yapmaya devam etmesi gerekti\u011fini bildirmektedir.\n<\/td>\n<\/tr>\n<tr>\n<td><em>Data de\u011fi\u015fikli\u011finden sonraki ilk request<\/em><\/td>\n<td>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-4.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-4-300x150.jpg\" alt=\"Asp.NET Core - ETag Nedir? ETag \u0130le Response Caching \u0130\u015flemi Nas\u0131l Ger\u00e7ekle\u015ftirilir?\" width=\"300\" height=\"150\" class=\"aligncenter size-medium wp-image-18567\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-4-300x150.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-4.jpg 742w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nKaynaktaki veriler \u00fczerinde oynad\u0131ktan sonra request header&#8217;\u0131nda &#8216;If-None-Match&#8217; parametresi oldu\u011fu halde yap\u0131lan request neticesinde sunucuda ETag de\u011feri e\u015fle\u015fmeyecek ve data&#8217;da de\u011fi\u015fiklik oldu\u011fu alg\u0131lanarak 200 Status Code de\u011feri ile client&#8217;a g\u00f6nderilecektir.\n<\/td>\n<\/tr>\n<tr>\n<td><em>Data de\u011fi\u015fikli\u011finden sonraki ikinci request<\/em><\/td>\n<td>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-5.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-5-300x123.jpg\" alt=\"Asp.NET Core - ETag Nedir? ETag \u0130le Response Caching \u0130\u015flemi Nas\u0131l Ger\u00e7ekle\u015ftirilir?\" width=\"300\" height=\"123\" class=\"aligncenter size-medium wp-image-18570\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-5-300x123.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/Asp.NET-Core-ETag-Nedir-ETag-Ile-Response-Caching-Islemi-Nasil-Gerceklestirilir.-5.jpg 733w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nYine &#8216;If-None-Match&#8217;e yeni gelen ETag de\u011ferini vererek istekte bulunuyoruz. Sonu\u00e7 olarak 304 Status Code&#8217;u e\u015fli\u011finde d\u00f6ng\u00fc devam etmektedir&#8230;\n<\/td>\n<\/tr>\n<\/table>\n<h3 style=\"color:#e83e8c;\">Angular&#8217;da Basit Bir ETag Algoritmas\u0131<\/h3>\n<p>Olaki herhangi bir UI teknolojisinde ETag yap\u0131lanmas\u0131n\u0131 kullanman\u0131z gerekebilir. B\u00f6yle bir duruma istinaden Angular \u00fczerinden a\u015fa\u011f\u0131da verilene benzer bir \u00e7al\u0131\u015fmay\u0131 \u00f6rnek alabilir ve uygulayabilirsiniz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { HttpClient, HttpHeaders, HttpResponse } from '@angular\/common\/http';\r\nimport { Component } from '@angular\/core';\r\nimport { EtagService } from '.\/services\/etag.service';\r\n\r\n@Component({\r\n  selector: 'app-root',\r\n  templateUrl: '.\/app.component.html',\r\n  styleUrls: &#x5B;'.\/app.component.css'],\r\n})\r\nexport class AppComponent {\r\n  constructor(\r\n    private httpCLient: HttpClient,\r\n    private etagService: EtagService\r\n  ) {}\r\n\r\n  getir() {\r\n    this.httpCLient\r\n      .get('https:\/\/localhost:5001\/api\/orders', {\r\n        observe: 'response',\r\n        headers:\r\n          this.etagService.ETag != null\r\n            ? new HttpHeaders({ 'If-None-Match': this.etagService.ETag })\r\n            : null,\r\n      })\r\n      .subscribe((data) =&gt; {\r\n        console.log(data.headers.get('etag'));\r\n        this.etagService.ETag = data.headers.get('etag');\r\n      });\r\n  }\r\n}\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Injectable } from '@angular\/core';\r\n\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class EtagService {\r\n  ETag = &quot;&quot;;\r\n}\r\n<\/pre>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek uygulamay\u0131 indirebilmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/10\/ETagExample.zip\">buraya<\/a> t\u0131klay\u0131n\u0131z.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde client ile server aras\u0131ndaki ili\u015fkiyi daha performansl\u0131 ve server&#8217;da ki i\u015f y\u00fck\u00fcn\u00fc daha az maliyetli hale getirmek i\u00e7in d\u00fc\u015f\u00fcn\u00fclm\u00fc\u015f olan ve HTTP response&#8217;unda client&#8217;a g\u00f6nderilen bir bilgi olarak kar\u015f\u0131m\u0131za \u00e7\u0131kan ETag&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":9596,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3102],"tags":[2679,3863,3864,3865,3862],"class_list":["post-18501","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-asp-net-core","tag-asp-net-core","tag-asp-net-core-etag","tag-etag","tag-etag-response-cache","tag-if-none-match"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/18501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=18501"}],"version-history":[{"count":64,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/18501\/revisions"}],"predecessor-version":[{"id":18575,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/18501\/revisions\/18575"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/9596"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=18501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=18501"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=18501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}