﻿
{"id":28194,"date":"2025-12-07T10:55:43","date_gmt":"2025-12-07T10:55:43","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=28194"},"modified":"2025-12-07T10:55:43","modified_gmt":"2025-12-07T10:55:43","slug":"unsafeaccessorattribute-ile-yeni-bir-reflection-yaklasimi","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/unsafeaccessorattribute-ile-yeni-bir-reflection-yaklasimi\/","title":{"rendered":"UnsafeAccessorAttribute \u0130le Yeni Bir Reflection Yakla\u015f\u0131m\u0131"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde, .NET 8 ile sunulan <code>UnsafeAccessorAttribute<\/code>&#8216;u ile reflection davran\u0131\u015f\u0131na dair yeni bir yakla\u015f\u0131m\u0131 de\u011ferlendirecek ve bir yandan da klasik yakla\u015f\u0131mla mukayese ederek, \u00f6rnek kullan\u0131m senaryolar\u0131 \u00fczerinden getirisi olan avantajlar\u0131 ve riskleri tart\u0131\u015f\u0131yor olaca\u011f\u0131z.<\/p>\n<p>Bilindi\u011fi \u00fczere C#&#8217;ta, t\u00fcrler \u00fczerinde runtime incelemelerini ve dinamik etkile\u015fimleri reflection davran\u0131\u015f\u0131 ile ger\u00e7ekle\u015ftirmekteyiz. \u00d6zellikle bu davran\u0131\u015f bizler a\u00e7\u0131s\u0131ndan, ORM gibi yakla\u015f\u0131mlarda yahut <a href=\"https:\/\/www.gencayyildiz.com\/blog\/tag\/dependency-injection\/\" target=\"_blank\">Dependency Injection<\/a> gibi pattern&#8217;larda vazge\u00e7ilmez \u00e7\u00f6z\u00fcmler sa\u011flamaktad\u0131r diyebiliriz. Ancak reflection tabanl\u0131 \u00e7\u00f6z\u00fcmlerin performans ve maliyet a\u00e7\u0131s\u0131ndan \u00f6nemli bedeller do\u011furdu\u011funu biliyoruz. Haliyle bizler bu i\u00e7eri\u011fimizde, .NET 8 ile gelmi\u015f olan <code>UnsafeAccessorAttribute<\/code> ile birlikte, geleneksel reflection modelini tamamlay\u0131c\u0131 nitelikte olan ve d\u00fc\u015f\u00fck seviyeli fakat olduk\u00e7a y\u00fcksek performansl\u0131 olarak eri\u015fim davran\u0131\u015f\u0131n\u0131 sa\u011flayan yeni bir mekanizmay\u0131 de\u011ferlendirecek ve mevzu bahis olan bu maliyet ve bedelleri yerine g\u00f6re nas\u0131l minimize edebildi\u011fimizi inceleyece\u011fiz.<\/p>\n<blockquote><p><em>Reflection ile ilgili mutlak bilgi i\u00e7in <a href=\"https:\/\/www.youtube.com\/watch?v=5SiAm7PlOOU&#038;list=PLQVXoXFVVtp1yha_meMc706hDgz4WAvHH&#038;index=5\" target=\"_blank\">Derinlemesine Reflection Davran\u0131\u015f\u0131<\/a> ba\u015fl\u0131kl\u0131 e\u011fitimime g\u00f6z atabilirsiniz.<\/em><\/p><\/blockquote>\n<h4>Klasik reflection&#8217;da ne sorun vard\u0131?<\/h4>\n<p>Klasik reflection yakla\u015f\u0131m\u0131, runtime&#8217;da meta veri ke\u015ffi sa\u011flayarak esneklik sunmakla birlikte, performans maliyeti ve <a href=\"https:\/\/www.gencayyildiz.com\/blog\/net-8-minimal-api-ahead-of-timeaot-compilation-template\/\" target=\"_blank\">Native AOT (Ahead-of-Time)<\/a> senaryolar\u0131ndaki k\u0131s\u0131tlar\u0131 nedeniyle s\u0131kl\u0131kla ele\u015ftirilmektedir.<\/p>\n<p>\u015e\u00f6yle ki;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic class Person\r\n{\r\n    public Person() { }\r\n    public Person(string fullName)\r\n        =&gt; _fullName = fullName;\r\n\r\n    public string FirstName { get; set; } = string.Empty;\r\n    public string MiddleName { get; set; } = string.Empty;\r\n    public string LastName { get; set; } = string.Empty;\r\n\r\n    public string _fullName;\r\n\r\n    public string GetFullName()\r\n        =&gt; $&quot;{FirstName} {LastName}&quot;.Trim();\r\n\r\n    public void Rename(string first, string? middle, string last)\r\n    {\r\n        FirstName = first ?? string.Empty;\r\n        MiddleName = middle ?? string.Empty;\r\n        LastName = last ?? string.Empty;\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>Misal olarak elimizde yukar\u0131daki gibi bir s\u0131n\u0131f\u0131n oldu\u011funu varsayal\u0131m&#8230; Bu s\u0131n\u0131f\u0131n FirstName property&#8217;sine reflection ile eri\u015fmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131zda a\u015fa\u011f\u0131daki gibi bir yakla\u015f\u0131m sergilememiz gerekmektedir;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar firstNameProperty = typeof(Person)\r\n    .GetProperty(nameof(Person.FirstName));\r\n<\/pre>\n<\/div>\n<p>Bu yakla\u015f\u0131mda;<\/p>\n<ul>\n<li>Metadata&#8217;lar runtime&#8217;da okunmaktad\u0131r.<\/li>\n<li>Veriler Boxing \/ Unboxing i\u015flemlerine tabi tutulmaktad\u0131r.<\/li>\n<li>AOT \/ trimming senaryolar\u0131nda \u00e7o\u011fu zaman s\u0131k\u0131nt\u0131 \u00e7\u0131kma ihtimali ta\u015f\u0131maktad\u0131r.<\/li>\n<li>JIT i\u00e7in optimize i\u015flemi zorludur, bu y\u00fczden yava\u015f i\u015flevsellik s\u00f6z konusu olabilmektedir.<\/li>\n<\/ul>\n<p>Bunca bedele kar\u015f\u0131n, <code>UnsafeAccessorAttribute<\/code> ise derleme zaman\u0131nda static binding imkan\u0131 sa\u011flayarak, private member&#8217;larda dahil olmak \u00fczere t\u00fcr i\u00e7i \u00f6\u011felere neredeyse do\u011frudan \u00e7a\u011fr\u0131 ile eri\u015fim sunmaktad\u0131r.<\/p>\n<h4>UnsafeAccessorAttribute \u0130le Yeni Yakla\u015f\u0131m<\/h4>\n<p><em>System.Runtime.CompilerServices<\/em> namespace&#8217;i alt\u0131nda bulunan <code>UnsafeAccessorAttribute<\/code>, a\u015fa\u011f\u0131daki fikir \u00fczerine in\u015fa edilmi\u015ftir.<\/p>\n<blockquote><p><em style=\"color:green;\">Eri\u015fim yapaca\u011f\u0131m member tam olarak belli; ismi ve imzas\u0131 derleme zaman\u0131nda a\u015fikar. O halde reflection ile \u00e7al\u0131\u015fma zaman\u0131nda meta veri arama maliyetine katlanmadan, do\u011frudan bu member&#8217;a ba\u011flanmak istiyorum.<\/em><\/p><\/blockquote>\n<p>Bu attribute&#8217;u kullanabilmek i\u00e7in g\u00f6vdesi olmayan (extern) static metotlar tan\u0131mlamam\u0131z gerekmektedir. Bu metotlar\u0131n imzas\u0131, eri\u015filmek istenen member&#8217;\u0131n imzas\u0131 ile e\u015fle\u015ftirilir ve CLR bu e\u015fle\u015ftirmeyi kullanarak derleme zaman\u0131nda uygun \u00e7a\u011fr\u0131 noktas\u0131n\u0131 \u00fcretir.<\/p>\n<p>\u015e\u00f6yle ki;<\/p>\n<p><u><em>Eski yol:<\/em><\/u><\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nperson.GetType()\r\n    .GetField(&quot;_fullName&quot;)!\r\n    .SetValue(person, &quot;Gen\u00e7ay YILDIZ&quot;);\r\n<\/pre>\n<\/div>\n<p><u><em>Yeni yol:<\/em><\/u><\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;UnsafeAccessor(UnsafeAccessorKind.Field, Name = &quot;_fullName&quot;)]\r\nstatic extern ref string SetPersonFullName(Person person);\r\n\r\nSetPersonFullName(person) = &quot;Gen\u00e7ay YILDIZ&quot;;\r\n<\/pre>\n<\/div>\n<p>Bak\u0131n&#8230; Bu \u00f6rnekte g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere <code>UnsafeAccessorAttribute<\/code> ile static extern olan bir metodu i\u015faretleyerek, <code>UnsafeAccessorKind.Field<\/code> parametresiyle de bu metodun esas\u0131nda bir field&#8217;a bind olaca\u011f\u0131n\u0131 ifade etmi\u015f bulunuyoruz. CLR, compile time&#8217;da bu ba\u011flant\u0131y\u0131 \u00e7\u00f6zerek do\u011frudan o member&#8217;a \u00e7a\u011fr\u0131 \u00fcretecektir ve b\u00f6ylece reflection olmaks\u0131z\u0131n m\u0131\u015f gibi bir davran\u0131\u015fla bu i\u015flem daha az maliyetle ger\u00e7ekle\u015ftirilmi\u015f olacakt\u0131r.<\/p>\n<p>Ayr\u0131ca buradaki kullan\u0131ma odaklan\u0131rsak e\u011fer <code>SetPersonFullName(person) = \"Gen\u00e7ay YILDIZ\"<\/code> ifadesinin pek al\u0131\u015f\u0131lagelmi\u015f bir kullan\u0131m olmad\u0131\u011f\u0131n\u0131 s\u00f6yleyebiliriz. Ne de olsa sanki bir metot \u00e7a\u011fr\u0131m\u0131n\u0131n \u00fczerine bir de\u011fer at\u0131yormu\u015f gibi zahiren bir g\u00f6r\u00fcnt\u00fc mevzu bahis \ud83d\ude42 Evet, bu g\u00f6r\u00fcnt\u00fc sa\u00e7ma bir mant\u0131k yans\u0131t\u0131yor olabilir ama esas\u0131nda izah\u0131 olduk\u00e7a kolay. \u015e\u00f6yle ki; ilgili static extern olan metodun yap\u0131s\u0131na bakarsan\u0131z e\u011fer <a href=\"https:\/\/www.gencayyildiz.com\/blog\/c-7-0-ref-returns\/\" target=\"_blank\">ref string<\/a> ifadesini g\u00f6receksiniz. Bu ifade ile bu metodun bir string de\u011fer d\u00f6nd\u00fcrmesinden \u00f6te, bir string t\u00fcrde referans d\u00f6nd\u00fcrd\u00fc\u011f\u00fcn\u00fc anl\u0131yoruz. Yani bu imza bir de\u011fer d\u00f6nd\u00fcren metottan ziyade geriye bir referans d\u00f6nd\u00fcren yap\u0131ya sahiptir. Haliyle  buradaki  <code>SetPersonFullName(person) = \"Gen\u00e7ay YILDIZ\"<\/code> ifadesi C# compiler a\u00e7\u0131s\u0131ndan metodun d\u00f6nd\u00fcrd\u00fc\u011f\u00fc referansa &#8216;Gen\u00e7ay YILDIZ&#8217; de\u011ferini atamaktad\u0131r \ud83d\ude42 \u0130\u015fte esas\u0131nda t\u00fcm mesele bundan ibarettir&#8230;<\/p>\n<p>Asl\u0131nda C#&#8217;\u0131n bu <a href=\"https:\/\/www.gencayyildiz.com\/blog\/c-7-0-ref-returns\/\" target=\"_blank\">Ref Returns<\/a> \u00f6zelli\u011fine a\u015fina olanlar i\u00e7in yukar\u0131daki bu yap\u0131n\u0131n esas\u0131nda a\u015fa\u011f\u0131dakinden bir fark\u0131n\u0131n olmad\u0131\u011f\u0131 rahatl\u0131kla anla\u015f\u0131labilecektir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;UnsafeAccessor(UnsafeAccessorKind.Field, Name = &quot;_fullName&quot;)]\r\nstatic extern ref string SetPersonFullName(Person person);\r\n\r\nref string fullName = ref SetPersonFullName(person);\r\nfullName = &quot;Gen\u00e7ay YILDIZ&quot;;\r\n<\/pre>\n<\/div>\n<p>Evet, ne de olsa <code>SetPersonFullName<\/code> metodundan gelen referans\u0131 yine <em>ref<\/em> ile i\u015faretlenmi\u015f(yani bir de\u011fer de\u011fil de bir referans\u0131 i\u015faretleyecek olan) bir de\u011fi\u015fkenle kar\u015f\u0131layarak o de\u011fi\u015fken arac\u0131l\u0131\u011f\u0131yla gelen referans \u00fczerinde gerekli dokunu\u015flar\u0131 ger\u00e7ekle\u015ftirebilmekteyiz. Bu iki kullan\u0131mda \u00f6z\u00fcnde ayn\u0131 davran\u0131\u015f\u0131 sergiledi\u011fi i\u00e7in aralar\u0131nda hi\u00e7bir fark s\u00f6z konusu de\u011fildir.<\/p>\n<p>Tabi <code>UnsafeAccessorAttribute<\/code>&#8216;u yaln\u0131zca field&#8217;lar da kullanmakla s\u0131n\u0131rl\u0131 de\u011filiz. \u0130htiya\u00e7 do\u011frultusunda metotlarda ve hatta constructor&#8217;larda da bu attribute&#8217;u tercih edebilmekteyiz.<\/p>\n<p><strong>Metotlarda kullan\u0131m<\/strong><\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(Person.GetFullName))]\r\nstatic extern string GetPersonFullName(Person person);\r\n\r\nvar fullName = GetPersonFullName(person);\r\n<\/pre>\n<\/div>\n<p>Evet, g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere compile time&#8217;da <code>UnsafeAccessorAttribute<\/code>&#8216;u ile bir metodu i\u015faretleyebilmek i\u00e7in static extern metodunun imzas\u0131n\u0131 birebir o metotla ayn\u0131 yapmam\u0131z yeterli olacakt\u0131r. Bak\u0131n bu sefer metodun geri d\u00f6n\u00fc\u015f de\u011ferini <em>ref<\/em> ile i\u015faretlemedi\u011fimize dikkatinizi \u00e7ekerim. Haliyle bu \u015fekilde bir imzayla salt bir metodu ifade etti\u011fimiz alenen ortada olmaktad\u0131r. Dolay\u0131s\u0131yla kullan\u0131rken de direkt metot \u00e7a\u011fr\u0131m\u0131 davran\u0131\u015f\u0131yla kullan\u0131yoruz.<\/p>\n<p><strong>Constructor&#8217;larda kullan\u0131m<\/strong><br \/>\n\u0130lgin\u00e7tir ki <code>UnsafeAccessorAttribute<\/code>&#8216;unu constructor&#8217;larda bile kullanabilmekteyiz.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;UnsafeAccessor(UnsafeAccessorKind.Constructor)]\r\nstatic extern Person PersonInitialize(string fullName);\r\nPerson person = PersonInitialize(&quot;Gen\u00e7ay YILDIZ&quot;);\r\n<\/pre>\n<\/div>\n<p>Burada g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere metot imzas\u0131nda belirtilen &#8216;Person&#8217; tipi sayesinde bir nesne olu\u015fturulaca\u011f\u0131 ifade edilmektedir ve compiler a\u00e7\u0131s\u0131ndan hangi constructor&#8217;\u0131n kullan\u0131laca\u011f\u0131na da implicit olarak klasik parametre say\u0131s\u0131 ve t\u00fcr se\u00e7ilimine g\u00f6re e\u015fle\u015ftirme yap\u0131larak karar verilmektedir.<\/p>\n<p>Evet, bu a\u00e7\u0131dan bak\u0131ld\u0131\u011f\u0131nda <code>UnsafeAccessorAttribute<\/code>&#8216;unun olduk\u00e7a etkin yeteneklere sahip oldu\u011funu s\u00f6yleyebiliriz\ud83d\udc4f<\/p>\n<h4>G\u00fcvenlik, Bak\u0131m ve K\u0131s\u0131tlar<\/h4>\n<p>Her ne kadar sunulan model, performans ve AOT bak\u0131m\u0131ndan belirgin avantajlar sunuyor olsa da, ad\u0131ndaki &#8216;unsafe&#8217; nitelemesinin tesad\u00fcf olmad\u0131\u011f\u0131n\u0131 vurgulamak gerekmektedir. \u015e\u00f6yle ki; eri\u015filen member&#8217;\u0131n ad\u0131 de\u011fi\u015ftirildi\u011finde (\u00f6rne\u011fin _fullName yerine _name \u015feklinde bir de\u011fi\u015fiklik yap\u0131ld\u0131\u011f\u0131nda) burada compile time&#8217;da de\u011fil runtime&#8217;da hata s\u00f6z konusu olacakt\u0131r. Ee bu durumda da ilgili attribute&#8217;un implementasyon detay\u0131nda g\u00fc\u00e7l\u00fc bir ba\u011f\u0131ml\u0131l\u0131k durumunun s\u00f6z konusu oldu\u011funu s\u00f6yleyebiliriz. Bu tarz durumlar\u0131 <strong><em>K\u0131r\u0131lgan S\u00f6zle\u015fme (Fragile Contract)<\/em><\/strong> olarak nitelendirmekteyiz. Haliyle burada ciddi bir g\u00fcvensiz durum s\u00f6z konusudur diyebiliriz.<\/p>\n<p>Nihai olarak;<br \/>\n<code>UnsafeAccessorAttribute<\/code>, reflection davran\u0131\u015f\u0131n\u0131 tamamlayan yeni bir yap\u0131 ta\u015f\u0131 ortaya koymakta ve \u00e7al\u0131\u015fma zamanl\u0131 yap\u0131lan ke\u015fif s\u00fcre\u00e7leriyle, derleme zamanl\u0131 static binding aras\u0131nda yeni bir denge noktas\u0131 sunmaktad\u0131r. Bu attribute, \u00f6zellikle do\u011fru ba\u011flamda kullan\u0131ld\u0131\u011f\u0131 taktirde performans ve maliyet a\u00e7\u0131s\u0131ndan olduk\u00e7a kayda de\u011fer kazan\u0131mlar sa\u011flayabilmektedir. Ancak s\u00f6z konusu kazan\u00e7lar, elbetteki yukar\u0131daki sat\u0131rlarda ifade etmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z gibi belli ba\u015fl\u0131 ihlaller, bak\u0131m zorluklar\u0131 ve s\u0131n\u0131rl\u0131 dinamiklikler gibi bedellerle birlikte gelmektedir. Bundan kaynakl\u0131 <code>UnsafeAccessorAttribute<\/code> kullan\u0131m\u0131n\u0131n, yaln\u0131zca gerek\u00e7esi a\u00e7\u0131k\u00e7a temellendirilmi\u015f, iyi izole edilmi\u015f ve uzun vadeli etkileri do\u011fru de\u011ferlendirilmi\u015f senaryolarla s\u0131n\u0131rland\u0131r\u0131lmas\u0131n\u0131n sa\u011fl\u0131kl\u0131 bir tasar\u0131m olaca\u011f\u0131 kanaatindeyim.<\/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<p>Not : \u00d6rnek \u00e7al\u0131\u015fmaya a\u015fa\u011f\u0131daki GitHub adresinden eri\u015febilirsiniz.<br \/>\n<a href=\"https:\/\/github.com\/gncyyldz\/UnsafeAccessorAttribute.Example\" target=\"_blank\">https:\/\/github.com\/gncyyldz\/UnsafeAccessorAttribute.Example<\/a><\/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, .NET 8 ile sunulan UnsafeAccessorAttribute&#8216;u ile reflection davran\u0131\u015f\u0131na dair yeni bir yakla\u015f\u0131m\u0131 de\u011ferlendirecek ve bir yandan da klasik yakla\u015f\u0131mla mukayese ederek, \u00f6rnek kullan\u0131m senaryolar\u0131 \u00fczerinden getirisi olan avantajlar\u0131 ve riskleri tart\u0131\u015f\u0131yor&#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":3014,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5206,4912,2739,12],"tags":[4915,27,5542,5544,5543,1408,5541],"class_list":["post-28194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-net-8","category-net-core","category-c-sharp-c","tag-net-8","tag-c","tag-c-unsafeaccessorattribute","tag-fragile-contract","tag-kirilgan-sozlesme","tag-reflection","tag-unsafeaccessorattribute"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28194","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=28194"}],"version-history":[{"count":7,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28194\/revisions"}],"predecessor-version":[{"id":28201,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/28194\/revisions\/28201"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/3014"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=28194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=28194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=28194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}