﻿
{"id":18916,"date":"2020-11-09T20:55:00","date_gmt":"2020-11-09T20:55:00","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=18916"},"modified":"2020-11-09T20:55:00","modified_gmt":"2020-11-09T20:55:00","slug":"asp-net-core-api-versiyonlama","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-api-versiyonlama\/","title":{"rendered":"Asp.NET Core &#8211; API Versiyonlama"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>API geli\u015ftirilirken akl\u0131m\u0131zda tutmam\u0131z gereken bir realite vard\u0131r ki o da &#8216;De\u011fi\u015fim Ka\u00e7\u0131n\u0131lmazd\u0131r&#8217; ilkesidir. Geli\u015fim s\u00fcrecinde her ne kadar i\u015f odakl\u0131 bir \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftiriyor olsakta, k\u00e2h \u00f6ng\u00f6r\u00fclemeyen k\u00e2h sonradan do\u011fan ihtiya\u00e7lara binaen API&#8217;a daha fazla sorumluluk eklememiz gerekebilmektedir. \u0130\u015fte b\u00f6yle bir durumda yap\u0131lan de\u011fi\u015fikliklere istinaden API&#8217;lar\u0131n istemciler \u00fczerindeki etkisini y\u00f6netebilmek ve operasyonel olarak ger\u00e7ekle\u015ftirilen \u00e7al\u0131\u015fmay\u0131 raporlayabilmek i\u00e7in her bir g\u00fcncelleme neticesinde API&#8217;lar\u0131 versiyonlamam\u0131z gerekmektedir.<\/p>\n<p>API&#8217;lar\u0131 versiyonlayabilmek i\u00e7in <em>URL API Versioning<\/em>, <em>QueryString API Versioning<\/em> ve <em>Media\/Header API Versioning<\/em> gibi birbirlerinden farkl\u0131 avantajlara sahip birka\u00e7 yakla\u015f\u0131m s\u00f6z konusudur. Bizler bu i\u00e7eri\u011fimizde, bu yakla\u015f\u0131mlar e\u015fli\u011finde, Microsoft&#8217;un Asp.NET Core MVC Versiyon Olu\u015fturma(ASP.NET Core MVC Versioning) paketi ile Asp.NET Core RESTFul API&#8217;lerinin nas\u0131l s\u00fcr\u00fcmlendirildi\u011fini konu\u015fuyor olaca\u011f\u0131z.<\/p>\n<h3 style=\"color:#e83e8c;\">API&#8217;leri Neden Versiyonlamam\u0131z Gerekmektedir?<\/h3>\n<p>Esas\u0131nda bu gereksinim yaz\u0131l\u0131msal bir gelene\u011fin g\u00fcn\u00fcm\u00fczdeki tezah\u00fcr\u00fcd\u00fcr diyebiliriz. Bu gelenek ise s\u00f6zle\u015fmeli tasar\u0131m modeli(Design by contract) olan &#8216;Contract-Based Programming\/S\u00f6zle\u015fme Tabanl\u0131 Programlama&#8217;n\u0131n ta kendisidir. Eskiden -WebService \/ WCF- gibi hizmetler d\u00f6neminde \u00e7ok fazla tercih edilen s\u00f6zle\u015fme tabanl\u0131 programlama yakla\u015f\u0131m\u0131 g\u00fcn\u00fcm\u00fcz\u00fcn API teknolojisini modernize etme s\u00fcrecinde de temel ihtiya\u00e7 olarak kar\u015f\u0131m\u0131za \u00e7\u0131kmakta ve teknik olarak belli ba\u015fl\u0131 de\u011fi\u015fikliklerle birlikte yeni bir esas halini almaktad\u0131r.<\/p>\n<blockquote><p><em style=\"color:purple;\">Contract-Based Programming yakla\u015f\u0131m\u0131, client ile server aras\u0131na yerle\u015ftirilen bir s\u00f6zle\u015fme gere\u011fince veri transferinin ger\u00e7ekle\u015fmesini sa\u011flayan bir i\u015flevselli\u011fe sahiptir.<\/em><\/p><\/blockquote>\n<p>Versiyonlaman\u0131n geleneksel etkilerden ziyade esas itibariyle sahasal bir ihtiyac\u0131 s\u00f6z konusudur. Bu ihtiya\u00e7 esas\u0131nda API&#8217;lar da ki fiziksel g\u00fcncellemeler \u00fczerine olan client-server ili\u015fkisi \u00fczerinedir. Belli ba\u015fl\u0131 t\u00fcketiciler taraf\u0131ndan kullan\u0131lan API&#8217;lar da yap\u0131lan de\u011fi\u015fiklikler mevcut t\u00fcketiciler a\u00e7\u0131s\u0131ndan k\u0131r\u0131lmalara\/patlamalara sebep olacakt\u0131r. Dolay\u0131s\u0131yla bir de\u011fi\u015fiklikte \u00f6nemsenmesi gereken ilk fakt\u00f6r o API t\u00fcketicilerinin i\u015flevsel ak\u0131\u015flar\u0131nda ya\u015fanabilecek kesintilerdir. B\u00f6yle bir durumda client&#8217;lar\u0131n API ile kurdu\u011fu etkile\u015fim bi\u00e7imini tan\u0131mlamakta \u00e7ok b\u00fcy\u00fck fayda vard\u0131r. <\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-1.jpg\"><img decoding=\"async\" style=\"width:300px;height:300px;\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-1.jpg\" alt=\"Asp.NET Core - API Versiyonlama\" class=\"alignleft size-full wp-image-18926\" \/><\/a><br \/>\nClient&#8217;\u0131n API ile etkile\u015fim kurma bi\u00e7imi yandaki g\u00f6rselde oldu\u011fu gibidir. Burada &#8216;Employee&#8217; bir s\u00f6zle\u015fmeyi temsil etmekte ve her iki hizmetin de gerekli verileri iletebilmesi ve do\u011fru \u00e7al\u0131\u015fabilmesi i\u00e7in s\u00f6zle\u015fme format\u0131na uymas\u0131 gerekmektedir. S\u00f6zle\u015fmenin format\u0131nda yahut i\u00e7eri\u011finde bir de\u011fi\u015fiklik yap\u0131ld\u0131\u011f\u0131 zaman bu durum mevcut client&#8217;larda i\u015flevsel hatalara ve hatta patlamalara sebebiyet verebilmektedir.<br \/>\n<br \/>&nbsp;<br \/>\nBu hatalar\u0131n yahut patlamalar\u0131n olabilece\u011fi genel durumlar;<\/p>\n<ul>\n<li>API yollar\u0131n\u0131n yeniden adland\u0131r\u0131lmas\u0131,<\/li>\n<li>API metotlar\u0131n\u0131n g\u00fcncellenmesi(\u00fcretilen verilerin de\u011fi\u015fmesi),<\/li>\n<li>Hata kodlar\u0131ndaki de\u011fi\u015fiklikler,<\/li>\n<li>Veri format\u0131n\u0131n de\u011fi\u015ftirilmesi<\/li>\n<\/ul>\n<p>\u015feklinde tan\u0131mlanabilir.<\/p>\n<p>S\u00f6zle\u015fmenin bir di\u011fer \u00f6nemli hususu veri format\u0131d\u0131r. REST; json, xml, text vs. gibi bir\u00e7ok veri format\u0131n\u0131 desteklemektedir. <\/p>\n<blockquote><p><em style=\"color:purple;\">REST ile client&#8217;a asla ger\u00e7ek nesne g\u00f6nderilmez, ger\u00e7ek nesne yerine temsili olan JSON yahut di\u011fer formatlardaki de\u011ferler g\u00f6nderilir.<\/em><\/p><\/blockquote>\n<p>Client&#8217;\u0131n API ile kurdu\u011fu ili\u015fki ve veri format\u0131 yap\u0131lanmas\u0131ndan sonra esas soruya yani &#8216;<em>API\u2019leri Neden Versiyonlamam\u0131z Gerekmektedir?<\/em>&#8216; sorusuna gelirsek e\u011fer; bir API&#8217;da yap\u0131lan her bir de\u011fi\u015fiklik neticesinde, API ile o API&#8217;yi t\u00fcketen client aras\u0131ndaki ili\u015fkiyi zedelememek i\u00e7in ilgili client&#8217;\u0131 haberdar etmemiz gerekmektedir. \u0130\u015fte burada versiyonlama yeterince efektif bir \u00e7\u00f6z\u00fcm getirmekte ve url&#8217;de ki say\u0131sal bir de\u011fer \u00fczerinde sadece ufak bir aritmetik i\u015flem neticesinde client&#8217;\u0131 bilgilendirmekte ve \u00e7ark\u0131n kald\u0131\u011f\u0131 yerden devam etmesini sa\u011flamaktad\u0131r.<\/p>\n<p>Ek ilave olarak API&#8217;da yap\u0131lan de\u011fi\u015fiklikleri raporlamak ve en son de\u011fi\u015fikli\u011fe istinaden API&#8217;\u0131n g\u00fcncelli\u011fini vurgulamak ama\u00e7l\u0131 versiyonlama ger\u00e7ekle\u015ftirilmektedir.<\/p>\n<h3 style=\"color:#e83e8c;\">Ba\u015flarken<\/h3>\n<p>\u0130lk olarak \u00f6rneklendirmede bize e\u015flik edebilmesi i\u00e7in elimizin alt\u0131nda hali haz\u0131rda bir Asp.NET Core Web API uygulamas\u0131n\u0131n bulunmas\u0131 gerekmektedir. Haliyle \u00f6ncelikle bir Web API projesi olu\u015ftural\u0131m ve i\u00e7erisine a\u015fa\u011f\u0131daki controller&#8217;\u0131 ekleyelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    public class EmployeesController : ControllerBase\r\n    {\r\n        public IActionResult Get()\r\n        {\r\n            string&#x5B;] employees = { &quot;Nevin&quot;, &quot;Fatih&quot;, &quot;Hacer&quot;, &quot;\u0130brahim&quot; };\r\n            return Ok(employees);\r\n        }\r\n    }\r\n<\/pre>\n<p><span style=\"font-size:11px;\"><em>Bu s\u00fcre\u00e7te \u00f6rneklendirme yapaca\u011f\u0131m\u0131z controller&#8217;d\u0131r.<\/em><\/span><\/p>\n<p>Ard\u0131ndan ilgili projede versiyonlama operasyonlar\u0131n\u0131 y\u00fcr\u00fctebilmek i\u00e7in <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.AspNetCore.Mvc.Versioning\" rel=\"noopener noreferrer\" target=\"_blank\">Microsoft.AspNetCore.Mvc.Versioning<\/a> paketini y\u00fckleyelim.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-2.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-2.jpg\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"538\" height=\"138\" class=\"aligncenter size-full wp-image-18944\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-2.jpg 538w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-2-300x77.jpg 300w\" sizes=\"auto, (max-width: 538px) 100vw, 538px\" \/><\/a><\/p>\n<p>\u0130lgili paketi y\u00fckledikten sonra uygulaman\u0131n &#8216;Startup.cs&#8217; dosyas\u0131nda versiyonlama i\u015flemini y\u00fcr\u00fctecek &#8216;AddApiVersioning&#8217; servisini \u00e7a\u011f\u0131ral\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddControllers();\r\n            services.AddApiVersioning();\r\n        }\r\n\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>Bu i\u015flem neticesinde art\u0131k uygulamam\u0131za versiyonlama servisi y\u00fcklenmi\u015ftir. \u015eimdi bir ka\u00e7 ufak tefek temel konfig\u00fcrasyona de\u011finerek temeli derinle\u015ftirelim;<\/p>\n<h5 style=\"color:green;\">Varsay\u0131lan(Default) Versiyon Belirleme<\/h5>\n<p>Mevcut haliyle API&#8217;a bir GET iste\u011fi g\u00f6nderildi\u011finde a\u015fa\u011f\u0131daki hatayla kar\u015f\u0131la\u015f\u0131lmaktad\u0131r;<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-3.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-3.jpg\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"888\" height=\"78\" class=\"aligncenter size-full wp-image-18947\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-3.jpg 888w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-3-300x26.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-3-768x67.jpg 768w\" sizes=\"auto, (max-width: 888px) 100vw, 888px\" \/><\/a><br \/>\nHatan\u0131n metinsel hali;<br \/>\n<span style=\"color:green;background-color:#EFE0DD;font-size:13px;\">{&#8220;error&#8221;:{&#8220;code&#8221;:&#8221;ApiVersionUnspecified&#8221;,&#8221;message&#8221;:&#8221;An API version is required, but was not specified.&#8221;,&#8221;innerError&#8221;:null}}<\/span><\/p>\n<p>Bu hatayla varsay\u0131lan s\u00fcr\u00fcm bilgisi girilmedi\u011finden dolay\u0131 kar\u015f\u0131la\u015fmaktay\u0131z. Request url&#8217;inde API&#8217;a dair bir s\u00fcr\u00fcm bilgisi belirtilmedi\u011fi durumlarda taraf\u0131m\u0131zca varsay\u0131lan bir versiyonun belirtilmesi gerekmektedir. Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi &#8216;AssumeDefaultVersionWhenUnspecified&#8217; \u00f6zelli\u011fi kullan\u0131labilir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddControllers();\r\n            services.AddApiVersioning(_ =&gt;\r\n            {\r\n                _.DefaultApiVersion = new ApiVersion(1, 0);\r\n                _.AssumeDefaultVersionWhenUnspecified = true;\r\n            });\r\n        }\r\n\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>Yap\u0131lan bu konfig\u00fcrasyon neticesinde; &#8216;AssumeDefaultVersionWhenUnspecified&#8217; \u00f6zelli\u011fine true de\u011feri set edilerek, endpoint&#8217;te herhangi bir s\u00fcr\u00fcm belirtilmedi\u011fi taktirde 1.0 versiyonu varsay\u0131lan olarak kabul edilmektedir.<\/p>\n<p>Haliyle son durumda a\u015fa\u011f\u0131daki gibi API&#8217;a yap\u0131lan istekte url&#8217;de bir versiyon bilgisi bulunmad\u0131\u011f\u0131ndan dolay\u0131 compiler versiyonu 1.0 varsaymakta ve iste\u011fi ba\u015far\u0131yla d\u00f6nd\u00fcrmektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-4.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-4.jpg\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"403\" height=\"66\" class=\"aligncenter size-full wp-image-18953\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-4.jpg 403w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-4-300x49.jpg 300w\" sizes=\"auto, (max-width: 403px) 100vw, 403px\" \/><\/a><\/p>\n<h5 style=\"color:green;\">Client&#8217;\u0131 Desteklenen T\u00fcm S\u00fcr\u00fcmlerden Haberdar Etme<\/h5>\n<p>Bir API&#8217;\u0131n versiyonlar\u0131n\u0131 belirtebilmek i\u00e7in ilgili controller&#8217;\u0131 &#8216;ApiVersion&#8217; attribute&#8217;u ile i\u015faretlememiz gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    &#x5B;ApiVersion(&quot;1.0&quot;)]\r\n    &#x5B;ApiVersion(&quot;1.1&quot;)]\r\n    &#x5B;ApiVersion(&quot;1.2&quot;)]\r\n    &#x5B;ApiVersion(&quot;2.0&quot;)]\r\n    public class EmployeesController : ControllerBase\r\n    {\r\n        public IActionResult Get()\r\n        {\r\n            string&#x5B;] employees = { &quot;Nevin&quot;, &quot;Fatih&quot;, &quot;Hacer&quot;, &quot;\u0130brahim&quot; };\r\n            return Ok(employees);\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki gibi birden fazla versiyona sahip olan bir controller&#8217;\u0131n destekledi\u011fi t\u00fcm versiyonlar\u0131 client&#8217;a bilgilendirmek i\u00e7in &#8216;ReportApiVersions&#8217; \u00f6zelli\u011finin &#8216;true&#8217; olmas\u0131 gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddControllers();\r\n            services.AddApiVersioning(_ =&gt;\r\n            {\r\n                _.DefaultApiVersion = new ApiVersion(1, 0);\r\n                _.AssumeDefaultVersionWhenUnspecified = true;\r\n                _.ReportApiVersions = true;\r\n            });\r\n        }\r\n\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-5.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-5.jpg\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"576\" height=\"606\" class=\"aligncenter size-full wp-image-18959\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-5.jpg 576w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-5-285x300.jpg 285w\" sizes=\"auto, (max-width: 576px) 100vw, 576px\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere response header&#8217;da <code>api-supported-versions<\/code> key&#8217;ine kar\u015f\u0131l\u0131k desteklenen t\u00fcm versiyon bilgileri client taraf\u0131ndan edinilmektedir.<\/p>\n<p>Ayriyetten controller seviyesinde kullan\u0131mdan kald\u0131r\u0131lan versiyonlar &#8216;Deprecated&#8217; \u00f6zelli\u011fine verilen &#8216;true&#8217; de\u011feri ile bildirilebilmekte ve b\u00f6ylece istek neticesinde client&#8217;a bildiri olarak g\u00f6nderilmemektedir. <\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiVersion(&quot;1.0&quot;, Deprecated = true)]\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-6.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-6.jpg\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"272\" height=\"25\" class=\"aligncenter size-full wp-image-18964\" \/><\/a><\/p>\n<h5 style=\"color:green;\">Action Seviyesinde S\u00fcr\u00fcm Olu\u015fturmay\u0131 Etkinle\u015ftirme<\/h5>\n<p>Action seviyesinde s\u00fcr\u00fcm olu\u015fturabilmek i\u00e7in &#8216;MapToApiVersion&#8217; attribute&#8217;u kullan\u0131lmaktad\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    &#x5B;ApiVersion(&quot;1.0&quot;)]\r\n    &#x5B;ApiVersion(&quot;1.1&quot;)]\r\n    &#x5B;ApiVersion(&quot;2.0&quot;)]\r\n    public class EmployeesController : ControllerBase\r\n    {\r\n        string&#x5B;] employees = { &quot;Nevin&quot;, &quot;Fatih&quot;, &quot;Hacer&quot;, &quot;\u0130brahim&quot; };\r\n        &#x5B;MapToApiVersion(&quot;1.0&quot;)]\r\n        public IActionResult Get()\r\n        {\r\n            return Ok(employees);\r\n        }\r\n        &#x5B;MapToApiVersion(&quot;1.1&quot;)]\r\n        &#x5B;HttpGet(&quot;{id}&quot;)]\r\n        public IActionResult GetById(int id)\r\n        {\r\n            return Ok(employees&#x5B;id]);\r\n        }\r\n        &#x5B;MapToApiVersion(&quot;2.0&quot;)]\r\n        public IActionResult GetLast()\r\n        {\r\n            return Ok(employees&#x5B;employees.Length - 1]);\r\n        }\r\n    }\r\n<\/pre>\n<p>B\u00f6ylece hangi action&#8217;\u0131n hangi versiyona kar\u015f\u0131l\u0131k geldi\u011fini g\u00f6rebilir ve kar\u0131\u015f\u0131kl\u0131l\u0131\u011f\u0131 engelleyebilirsiniz.<\/p>\n<p>Evet, b\u00f6ylece bir Asp.NET Core uygulamas\u0131nda API versiyonlayabilmek i\u00e7in olmas\u0131 gereken temeli atm\u0131\u015f bulunmaktay\u0131z. \u015eimdi s\u0131ras\u0131yla versiyonlama stratejilerini ele alabiliriz;<\/p>\n<h3 style=\"color:#e83e8c;\">Asp.NET Core Versiyonlama Stratejileri<\/h3>\n<h5 style=\"color:green;\">QueryString API Versioning<\/h5>\n<p>Bu stratejide her kaynak i\u00e7in url&#8217;e a\u015fa\u011f\u0131daki gibi bir versiyon bilgisi eklenmesi gerekmektedir.<br \/>\n<code style=\"color:red;font-size:15px;\">https:\/\/localhost:5001\/api\/employees<span style=\"color:blue;\">?<\/span><span style=\"color:orange;\">api-version=1.0<\/span><\/code><br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama.gif\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"800\" height=\"326\" class=\"aligncenter size-full wp-image-18972\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere query string versiyonlamada herhangi bir konfig\u00fcrasyona gerek kalmaks\u0131z\u0131n versiyon bilgisiyle e\u015fle\u015fen action direkt sonu\u00e7 d\u00f6nd\u00fcrmektedir.<\/p>\n<h5 style=\"color:green;\">Media\/Header API Versioning<\/h5>\n<p>Versiyonlama i\u00e7in bir ba\u015fka teknik ise header&#8217;a yerle\u015ftirilen s\u00fcr\u00fcm bilgisidir. Bu y\u00f6ntemi kullanabilmek i\u00e7in &#8216;ApiVersionReader&#8217; konfig\u00fcrasyonunun a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirilmesi gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n.\r\n.\r\n.\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddControllers();\r\n            services.AddApiVersioning(_ =&gt;\r\n            {\r\n                _.DefaultApiVersion = new ApiVersion(1, 0);\r\n                _.AssumeDefaultVersionWhenUnspecified = true;\r\n                _.ReportApiVersions = true;\r\n                _.ApiVersionReader = new HeaderApiVersionReader(&quot;api-version&quot;);\r\n            });\r\n        }\r\n.\r\n.\r\n.\r\n<\/pre>\n<p>&#8216;HeaderApiVersionReader&#8217; nesnesine verilen &#8216;api-version&#8217; de\u011feri, header&#8217;da s\u00fcr\u00fcm bilgisini ta\u015f\u0131yacak olan key&#8217;e kar\u015f\u0131l\u0131k gelmektedir. Bu konfig\u00fcrasyondan sonra a\u015fa\u011f\u0131daki gibi ilgili header key&#8217;ine kar\u015f\u0131l\u0131k verilen s\u00fcr\u00fcm bilgisiyle e\u015fle\u015fen action tetiklenmektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-1.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-1.gif\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"800\" height=\"452\" class=\"aligncenter size-full wp-image-18976\" \/><\/a><\/p>\n<h5 style=\"color:green;\">URL API Versioning<\/h5>\n<p>Versiyonlama i\u015fleminin bir ba\u015fka ve son stratejisi ise url versiyonlamad\u0131r. Bu y\u00f6ntemde versiyon bilgisi route parametresi olarak url&#8217;de ta\u015f\u0131nmaktad\u0131r. Haliyle query string versiyonlamaya nazaran, url fiziksel olarak versiyon bilgisiyle b\u00fct\u00fcnle\u015fiktir. Dolay\u0131s\u0131yla yeni versiyon yay\u0131nland\u0131\u011f\u0131nda client&#8217;\u0131n elindeki url&#8217;i g\u00fcncellemesi gerekecektir. Nihai olarak, bu yakla\u015f\u0131m, bir REST ilkesi olan <em>-belirli bir kayna\u011f\u0131n url&#8217;sinin asla de\u011fi\u015fmemesi gereklili\u011fi-<\/em>ni ihlal eden bir istisnai durum ta\u015f\u0131maktad\u0131r.<\/p>\n<p>Bu versiyonlama stratejisini uygulayabilmek i\u00e7in ilgili controller&#8217;\u0131n rotas\u0131nda a\u015fa\u011f\u0131daki parametrelerin bildirilmesi gerekmektedir;<br \/>\n<code style=\"color:red;font-size:15px;\"><strong>[Route(\"api\/<span style=\"color:blue;\">v<span style=\"color:green;\">{version:apiVersion}<\/span><\/span>\/[controller]\")]<\/strong><\/code><\/p>\n<p>S\u00f6zgelimi;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/v{version:apiVersion}\/&#x5B;controller]&quot;)]\r\n    &#x5B;ApiVersion(&quot;1.0&quot;)]\r\n    &#x5B;ApiVersion(&quot;1.1&quot;)]\r\n    &#x5B;ApiVersion(&quot;2.0&quot;)]\r\n    public class EmployeesController : ControllerBase\r\n    {\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>\u015feklinde olacakt\u0131r.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-2.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/11\/Asp.NET-Core-API-Versiyonlama-2.gif\" alt=\"Asp.NET Core - API Versiyonlama\" width=\"800\" height=\"457\" class=\"aligncenter size-full wp-image-18986\" \/><\/a><\/p>\n<p>Nihai olarak;<br \/>\nMakalemizin ba\u015flar\u0131nda da de\u011findi\u011fimiz gibi i\u015f gereksinimlerindeki \u00f6ng\u00fcr\u00fclemez durumlar\u0131n yahut s\u00fcre\u00e7teki ihtiya\u00e7lar\u0131n farkl\u0131la\u015fmas\u0131n\u0131n API&#8217;lara s\u00fcrekli de\u011fi\u015fiklik olarak yans\u0131mas\u0131ndan dolay\u0131 versiyonlaman\u0131n \u00f6neminden, client&#8217;lar\u0131 bozmadan s\u00fcr\u00fcmlemenin nas\u0131l ger\u00e7ekle\u015ftirildi\u011finden belli ba\u015fl\u0131 stratejiler e\u015fli\u011finde bahsetmi\u015f olduk.<\/p>\n<p>Okudu\u011funuz i\u00e7in te\u015fekk\u00fcr ederim.<\/p>\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<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, API geli\u015ftirilirken akl\u0131m\u0131zda tutmam\u0131z gereken bir realite vard\u0131r ki o da &#8216;De\u011fi\u015fim Ka\u00e7\u0131n\u0131lmazd\u0131r&#8217; ilkesidir. Geli\u015fim s\u00fcrecinde her ne kadar i\u015f odakl\u0131 bir \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftiriyor olsakta, k\u00e2h \u00f6ng\u00f6r\u00fclemeyen k\u00e2h sonradan do\u011fan ihtiya\u00e7lara binaen API&#8217;a&#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":18922,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3102],"tags":[3905,3913,2679,3904,3903,3910,3911,3912,3909,3906,3908,3907],"class_list":["post-18916","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-asp-net-core","tag-api-versiyonlama","tag-apiversion","tag-asp-net-core","tag-asp-net-core-api-versiyonlama","tag-asp-net-core-mvc-versioning","tag-contract-based-programming","tag-design-by-contract","tag-maptoapiversion","tag-media-header-api-versioning","tag-microsoft-aspnetcore-mvc-versioning","tag-querystring-api-versioning","tag-url-api-versioning"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/18916","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=18916"}],"version-history":[{"count":66,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/18916\/revisions"}],"predecessor-version":[{"id":18993,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/18916\/revisions\/18993"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/18922"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=18916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=18916"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=18916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}