﻿
{"id":20764,"date":"2021-02-05T12:17:34","date_gmt":"2021-02-05T12:17:34","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=20764"},"modified":"2021-02-05T12:17:34","modified_gmt":"2021-02-05T12:17:34","slug":"deadlines-ve-cancellation-ile-guvenilir-grpc-servisleri-gelistirmek","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/deadlines-ve-cancellation-ile-guvenilir-grpc-servisleri-gelistirmek\/","title":{"rendered":"Deadlines ve Cancellation \u0130le G\u00fcvenilir gRPC Servisleri Geli\u015ftirmek"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>gRPC k\u00fct\u00fcphanesi, client&#8217;lar taraf\u0131ndan yap\u0131lan istekleri kontrol edebilmek ve \u00f6zellikle ihtiyaca istinaden iptal edebilmek i\u00e7in <em>Deadlines<\/em> ve <em>Cancellation<\/em> \u00f6zelliklerini sunmaktad\u0131r. Bu i\u00e7eri\u011fimizde gRPC sistemlerde sunulan bu Deadlines ve Cancellation \u00f6zelliklerinin neden \u00f6nemli olduklar\u0131n\u0131 de\u011ferlendirecek ve nas\u0131l kullan\u0131labileceklerini ele alaca\u011f\u0131z.<\/p>\n<h3 style=\"color:#e83e8c;\">gRPC&#8217;de Deadlines<\/h3>\n<p>Deadlines, herhangi bir gRPC client&#8217;\u0131n\u0131n yapt\u0131\u011f\u0131 request&#8217;in ne kadarl\u0131k adil bir s\u00fcreye sahip olabilece\u011fini ifade etmektedir. Belirtilen tarih a\u015f\u0131ld\u0131\u011f\u0131 taktirde ilgili request iptal edilecek ve b\u00f6ylece olas\u0131 hatalarda yahut yanl\u0131\u015f davran\u0131\u015flarda servislerin s\u0131n\u0131rs\u0131z \u00e7al\u0131\u015fmas\u0131n\u0131 ve sunucu kaynaklar\u0131n\u0131 t\u00fcketmesini engelleyecektir.<\/p>\n<blockquote><p><em style=\"color:purple;\">Deadlines, g\u00fcvenilir uygulamalar i\u00e7in faydal\u0131 ve \u00f6nerilen bir \u00f6zelliktir.<\/em><\/p><\/blockquote>\n<p>Sistem taraf\u0131ndan tan\u0131mlanm\u0131\u015f(default) deadline zaman\u0131 yoktur. Dolay\u0131s\u0131yla manuel bir yap\u0131land\u0131rmada bulunulmad\u0131\u011f\u0131 s\u00fcrece request&#8217;lerde herhangi bir zaman s\u0131n\u0131r\u0131 s\u00f6z konusu olmayacakt\u0131r.<\/p>\n<p>\u00d6rnek ama\u00e7l\u0131 a\u015fa\u011f\u0131daki \u00e7al\u0131\u015fmay\u0131 ele al\u0131rsak e\u011fer;<\/p>\n<p>Client:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            var channel = GrpcChannel.ForAddress(&quot;https:\/\/localhost:5001&quot;);\r\n            var messageClient = new MessageClient(channel);\r\n            MessageResponse response = await messageClient.SendMessageAsync(new MessageRequest { Name = &quot;Gen\u00e7ay&quot;, Message = &quot;Selam olsun...&quot; }, deadline: DateTime.UtcNow.AddSeconds(5));\r\n            Console.WriteLine(response.ResponseMessage);\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere client<span style=\"font-size:12px;\">(messageClient)<\/span> nesnesinin &#8216;deadline&#8217; parametresiyle ilgili request&#8217;in ne kadarl\u0131k<span style=\"font-size:12px;\">(5 saniye)<\/span> bir \u00f6mre sahip oldu\u011funu bildirmi\u015f bulunmaktay\u0131z.<\/p>\n<p>Server:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public override async Task&lt;MessageResponse&gt; SendMessage(MessageRequest request, ServerCallContext context)\r\n        {\r\n            await Task.Delay(10000);\r\n            Console.WriteLine($&quot;{request.Name} isimli client'dan \\&quot;{request.Message}\\&quot; mesaj\u0131 al\u0131nm\u0131\u015ft\u0131r.&quot;);\r\n            return new MessageResponse\r\n            {\r\n                ResponseMessage = $&quot;Thanks - {request.Name}&quot;\r\n            };\r\n        }\r\n<\/pre>\n<p>Server&#8217;da ise <strong><em>3.<\/em><\/strong> sat\u0131rdaki <code style=\"color:red;\">await Task.Delay(10000)<\/code> komutu sayesinde client&#8217;ta ki deadline s\u00fcresini a\u015facak \u015fekilde bir oyalama yap\u0131yoruz.<\/p>\n<p>Bu vaziyette uygulamalar\u0131 derleyip, \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131zda&#8230; A\u015fa\u011f\u0131daki gibi sonu\u00e7la kar\u015f\u0131la\u015fmaktay\u0131z.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek.png\" alt=\"Deadlines ve Cancellation \u0130le G\u00fcvenilir gRPC Servisleri Geli\u015ftirmek\" width=\"436\" height=\"59\" class=\"aligncenter size-full wp-image-20775\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek.png 436w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-300x41.png 300w\" sizes=\"auto, (max-width: 436px) 100vw, 436px\" \/><\/a>Evet&#8230; Yap\u0131lan request neticesinde server, client&#8217;\u0131n belirledi\u011fi &#8216;deadline&#8217; de\u011ferini a\u015ft\u0131\u011f\u0131 i\u00e7in bir <em><strong>DeadlineExceeded<\/strong><\/em> hatas\u0131 f\u0131rlat\u0131lmaktad\u0131r.<\/p>\n<p>Ayr\u0131ca yap\u0131lan istek neticesinde server&#8217;a da deadline bilgisi &#8216;ServerCallContext&#8217; parametresi \u00fczerinden g\u00f6nderilmektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-1.png\" alt=\"Deadlines ve Cancellation \u0130le G\u00fcvenilir gRPC Servisleri Geli\u015ftirmek\" width=\"515\" height=\"161\" class=\"aligncenter size-full wp-image-20778\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-1.png 515w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-1-300x94.png 300w\" sizes=\"auto, (max-width: 515px) 100vw, 515px\" \/><\/a>Bu \u015fekilde ilgili veriye eri\u015febilmek server a\u00e7\u0131s\u0131ndan olas\u0131 iptal durumunda \u00f6nleyici aksiyonlar\u0131n al\u0131nmas\u0131n\u0131 sa\u011flayabilir.<\/p>\n<h5>\u0130\u015flemekte olan bir gRPC servisi \u00fczerinden, yeni bir gRPC \u00e7a\u011fr\u0131s\u0131 yap\u0131ld\u0131\u011f\u0131 durumlarda son tarih bilgisini aktarma<\/h5>\n<p>Client&#8217;tan istek alm\u0131\u015f ve hala i\u015flemekte olan bir gRPC servisi i\u00e7erisinde bir ba\u015fka gRPC \u00e7a\u011fr\u0131s\u0131 yap\u0131ld\u0131\u011f\u0131 durumlarda deadline bilgisi i\u00e7teki gRPC \u00e7a\u011fr\u0131s\u0131na iletilmelidir. Bunun i\u00e7in yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz &#8216;ServerCallContext&#8217; parametresi gayet kullan\u0131\u015fl\u0131 olabilir.<\/p>\n<div style=\"text-align:center;\"><em style=\"color:green;font-size:12px;\">A\u015fa\u011f\u0131daki \u00f6rnekte sonraki makalelerimizde ele alaca\u011f\u0131m\u0131z <strong><u>gRPC Factory Integration<\/u><\/strong> \u00fczerinden \u00f6rneklendirme ger\u00e7ekle\u015ftirilmektedir.<\/em><\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class MessageService : MessageBase\r\n    {\r\n        readonly Message2Client _client;\r\n        public MessageService(Message2Client message2Client)\r\n        {\r\n            _client = message2Client;\r\n        }\r\n        public override async Task&lt;MessageResponse&gt; SendMessage(MessageRequest request, ServerCallContext context)\r\n        {\r\n            await Task.Delay(2000);\r\n            Console.WriteLine($&quot;{request.Name} isimli client'dan \\&quot;{request.Message}\\&quot; mesaj\u0131 al\u0131nm\u0131\u015ft\u0131r.&quot;);\r\n\r\n            Message2Response response = await _client.SendMessage2Async(new Message2Request { Name = &quot;Gen\u00e7ay&quot;, Message = &quot;Selam olsun...&quot; }, deadline: context.Deadline);\r\n\r\n            return new MessageResponse\r\n            {\r\n                ResponseMessage = $&quot;Thanks - {request.Name}&quot;\r\n            };\r\n        }\r\n    }\r\n<\/pre>\n<p>Lakin her i\u00e7 i\u00e7e gRPC \u00e7a\u011fr\u0131s\u0131nda deadline de\u011ferlerini bu \u015fekilde manuel yazmak olduk\u00e7a zahmetli olacakt\u0131r. Ayr\u0131ca bu \u015fekilde bir operasyonun \u00e7ok oldu\u011fu senaryolarda deadline de\u011ferinin g\u00f6zden ka\u00e7\u0131r\u0131lma ihtimalini de de\u011ferlendirirsek e\u011fer deadline&#8217;\u0131n her iste\u011fe kar\u015f\u0131l\u0131k otomatik bir \u015fekilde ge\u00e7mesini sa\u011flamak daha efektif bir \u00e7\u00f6z\u00fcm olacakt\u0131r.<\/p>\n<p>Bunun i\u00e7in &#8216;Startup.cs&#8217; dosyas\u0131nda a\u015fa\u011f\u0131daki konfig\u00fcrasyonun yap\u0131lmas\u0131 yeterlidir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddGrpcClient&lt;Message2Client&gt;(o =&gt; o.Address = new Uri(&quot;https:\/\/localhost:5003&quot;)).EnableCallContextPropagation();\r\n            services.AddGrpc();\r\n        }\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere ilgili client servisi dependency injection i\u00e7in IoC container&#8217;\u0131na verilirken &#8216;EnableCallContextPropagation&#8217; metodu sayesinde ilgili client&#8217;a yap\u0131lacak isteklere bu servise gelen deadline bilgileriyle yap\u0131lmas\u0131n\u0131 sa\u011flam\u0131\u015f bulunmaktay\u0131z. Ayr\u0131ca buradaki \u00f6rneklendirmede sonraki makalelerimizde ele alaca\u011f\u0131m\u0131z <u><em>gRPC Factory Integration<\/em><\/u> tasar\u0131m\u0131ndan istifade edildi\u011finden bahsetmekte fayda oldu\u011fu kanaatindeyim.<br \/>\n<div id=\"attachment_20797\" style=\"width: 389px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-2.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-20797\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-2.png\" alt=\"Deadlines ve Cancellation \u0130le G\u00fcvenilir gRPC Servisleri Geli\u015ftirmek\" width=\"379\" height=\"144\" class=\"size-full wp-image-20797\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-2.png 379w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/02\/Deadlines-ve-Cancellation-Ile-Guvenilir-gRPC-Servisleri-Gelistirmek-2-300x114.png 300w\" sizes=\"auto, (max-width: 379px) 100vw, 379px\" \/><\/a><p id=\"caption-attachment-20797\" class=\"wp-caption-text\">\u0130\u015flemekte olan gRPC servisi i\u00e7erisinden farkl\u0131 bir servise yap\u0131lan t\u00fcm isteklerde ilgili deadline de\u011ferinin g\u00f6nderildi\u011fini g\u00f6rmekteyiz.<\/p><\/div><\/p>\n<h3 style=\"color:#e83e8c;\">gRPC&#8217;de Cancellation<\/h3>\n<p>Cancellation, gRPC istemcilerinin ihtiya\u00e7 halinde yahut var olan bir iste\u011fin art\u0131k ihtiyac\u0131na gerek kalmad\u0131\u011f\u0131 durumlarda ilgili iste\u011fi iptal etmesini sa\u011flayan bir \u00f6zelliktir. Bu durumu \u015f\u00f6yle bir \u00f6rnekle daha da netle\u015ftirebiliriz; Bir kullan\u0131c\u0131n\u0131n, girdi\u011fi bir web sayfas\u0131 \u00fczerinden ger\u00e7ek zamanl\u0131 g\u00fcncellemeleri yay\u0131nlayan gRPC iste\u011fi ba\u015flatt\u0131\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnelim. Kullan\u0131c\u0131y\u0131 bu istek s\u00fcresince sayfada tutabilece\u011fimizin garantisi olmad\u0131\u011f\u0131 ve her an \u00e7\u0131kma ihtimali oldu\u011fu i\u00e7in, olas\u0131 durumda ak\u0131\u015f\u0131 devam ettirmemeli ve sonland\u0131rma i\u015flemini ger\u00e7ekle\u015ftirmeliyiz. \u0130\u015fte b\u00f6yle bir durumda Cancellation \u00f6zelli\u011fi devreye girmekte ve iste\u011fi iptal edebilmemizi sa\u011flamaktad\u0131r.<\/p>\n<p>Ger\u00e7i yap\u0131lan iste\u011fi iptal edebilmek i\u00e7in ayriyetten Dispose&#8217;da edebilmekteyiz. \u015eimdi gelin bu iki durumu da a\u015fa\u011f\u0131daki \u00f6rnekle de\u011ferlendirelim.<\/p>\n<div style=\"text-align:center;\"><em style=\"color:green;font-size:12px;\">A\u015fa\u011f\u0131daki \u00f6rnekte client ile server aras\u0131ndaki ileti\u015fim <a href=\"https:\/\/www.gencayyildiz.com\/blog\/grpc-client-streaming-yontemiyle-client-ve-server-iletisimi\/\" rel=\"noopener noreferrer\" target=\"_blank\">client streaming<\/a> t\u00fcr\u00fcnden sa\u011flanmaktad\u0131r.<\/em><\/div>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            var channel = GrpcChannel.ForAddress(&quot;https:\/\/localhost:5001&quot;);\r\n            var messageClient = new MessageClient(channel);\r\n\r\n            CancellationTokenSource cancellationToken = new CancellationTokenSource();\r\n            AsyncClientStreamingCall&lt;MessageRequest, MessageResponse&gt; call = messageClient.SendMessage(cancellationToken: cancellationToken.Token);\r\n\r\n            var t1 = Task.Run(async () =&gt;\r\n             {\r\n                 int count = 0;\r\n                 while (true)\r\n                     await call.RequestStream.WriteAsync(new MessageRequest { Message = $&quot;mesaj {count++}&quot; });\r\n             });\r\n\r\n            var t2 = Task.Run(() =&gt;\r\n             {\r\n                 ConsoleKey key = Console.ReadKey().Key;\r\n\r\n                 if (key == ConsoleKey.D)\r\n                 {\r\n                     call.Dispose();\r\n                     Console.WriteLine(&quot;S\u00fcre\u00e7 dispose ile durduruldu.&quot;);\r\n                 }\r\n                 else if (key == ConsoleKey.C)\r\n                 {\r\n                     cancellationToken.Cancel();\r\n                     Console.WriteLine(&quot;S\u00fcre\u00e7 callationtoken ile durduruldu.&quot;);\r\n                 }\r\n             });\r\n\r\n            await Task.WhenAll(t1, t2);\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer; <strong><em>5.<\/em><\/strong> sat\u0131rda <code style=\"color:red;\">AsyncClientStreamingCall&lt;MessageRequest, MessageResponse&gt;<\/code> t\u00fcr\u00fcnden bir referansa al\u0131nan iste\u011fimiz parametre olarak &#8216;cancellationToken&#8217;<span style=\"font-size:12px;\">(CancellationTokenSource)<\/span> de\u011feri almaktad\u0131r. Haliyle referansa al\u0131nan bu istek ya <strong><em>20.<\/em><\/strong> sat\u0131rda oldu\u011fu gibi Dispose edilmekte ya da <strong><em>25.<\/em><\/strong> sat\u0131rda oldu\u011fu gibi cancellationToken ile iptal edilmektedir. Her iki durumda da ilgili istek iptal edilecek ve ak\u0131\u015f sonland\u0131r\u0131lacakt\u0131r.<\/p>\n<p>B\u00f6ylece gerekti\u011fi zaman gRPC \u00fczerinden ger\u00e7ekle\u015ftirilen e\u015fzamans\u0131z(asenkron\/async) operasyonlar l\u00fczumsuz yere sunucudaki kaynaklar\u0131 t\u00fcketmeyecektir.<\/p>\n<p>Haa! Unutmadan \u015fu \u00f6nemli bilgiyi de sizlerle payla\u015f\u0131p makalemizi \u00f6yle noktaland\u0131ral\u0131m&#8230; gRPC ile yap\u0131lan isteklerin iptal edilme durumlar\u0131nda alt \u00e7a\u011fr\u0131lara da bunu bildirmek i\u00e7in yine yukar\u0131da ele ald\u0131\u011f\u0131m\u0131z &#8216;EnableCallContextPropagation&#8217; fonksiyonunu kullanman\u0131z yeterli olacakt\u0131r. \u0130lgili fonksiyon, iptal edilen bir iste\u011fin i\u015flev s\u00fcrecindeki alt istekleri de iptal edecek ve b\u00f6ylece tam teferruatl\u0131 bir \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftirilmi\u015f olunacakt\u0131r.<\/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, gRPC k\u00fct\u00fcphanesi, client&#8217;lar taraf\u0131ndan yap\u0131lan istekleri kontrol edebilmek ve \u00f6zellikle ihtiyaca istinaden iptal edebilmek i\u00e7in Deadlines ve Cancellation \u00f6zelliklerini sunmaktad\u0131r. Bu i\u00e7eri\u011fimizde gRPC sistemlerde sunulan bu Deadlines ve Cancellation \u00f6zelliklerinin neden \u00f6nemli olduklar\u0131n\u0131&#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":20414,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4032],"tags":[4126,4065,4125,4124,4127],"class_list":["post-20764","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-grpc","tag-deadlineexceeded","tag-grpc","tag-grpc-cancellation","tag-grpc-deadlines","tag-grpc-factory-integration"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20764","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=20764"}],"version-history":[{"count":40,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20764\/revisions"}],"predecessor-version":[{"id":20808,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20764\/revisions\/20808"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/20414"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=20764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=20764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=20764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}