{"id":1736,"date":"2017-11-22T18:26:00","date_gmt":"2017-11-22T16:26:00","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=1736"},"modified":"2017-12-11T21:46:35","modified_gmt":"2017-12-11T18:46:35","slug":"introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/","title":{"rendered":"GraphQL&#8217;e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak"},"content":{"rendered":"<p>Merhaba arkada\u015flar.<\/p>\n<p>Bir s\u00fcredir yeni bir makale yazmaya f\u0131rsat bulamad\u0131m. Hatta bu makalenin bir k\u0131sm\u0131n\u0131 ise A\u011fustos ay\u0131nda yazm\u0131\u015ft\u0131m, fakat bir t\u00fcrl\u00fc tamamlayamam\u0131\u015ft\u0131m. :) Buldu\u011fum ilk f\u0131rsatta ise tamamlamay\u0131 ba\u015fard\u0131m.<\/p>\n<p>Herneyse, san\u0131r\u0131m\u00a0<strong>GraphQL\u00a0<\/strong>(ayr\u0131ca Asp.NET Core 2.0),\u00a0<strong>veri eri\u015fimi<\/strong> ve <strong>sorgulama<\/strong> \u00fczerine son d\u00f6nemlerin en pop\u00fcler konular\u0131 aras\u0131ndad\u0131r. <em>GraphQL<\/em> \u00f6zellikle g\u00fcn\u00fcm\u00fcz \u00e7a\u011f\u0131nda h\u0131zla geli\u015fen bu business ihtiya\u00e7lar\u0131na kar\u015f\u0131, veri eri\u015fimini ve geli\u015fmi\u015f sorgulamas\u0131n\u0131 client taraf\u0131na b\u0131rakarak,\u00a0<strong>h\u0131zl\u0131<\/strong> ve <strong>efficient<\/strong> bir \u015fekilde development yapabilme imkan\u0131n\u0131 biz developer&#8217;lara sunmaktad\u0131r.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/11\/FastEnough.jpg\"><img decoding=\"async\" class=\"aligncenter wp-image-1852 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/11\/FastEnough.jpg\" alt=\"\" width=\"751\" height=\"322\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/FastEnough.jpg 770w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/FastEnough-300x129.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/FastEnough-768x329.jpg 768w\" data-sizes=\"(max-width: 751px) 100vw, 751px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 751px; --smush-placeholder-aspect-ratio: 751\/322;\" \/><\/a><\/p>\n<p>\u00d6ncelikle <em>GraphQL<\/em> konusu,\u00a0benim i\u00e7inde yeni say\u0131labilecek bir konu. <em>GraphQL<\/em> ile hen\u00fcz production \u00fczerinde bir tecr\u00fcbe edinemedim. Fakat yak\u0131n bir d\u00f6nem i\u00e7erisinde \u00f6zellikle mobile API&#8217;lar\u0131m\u0131z i\u00e7in bir gateway gibi\u00a0<em>GraphQL<\/em> ile veri eri\u015fimi ve sorgulama i\u015flemlerini ger\u00e7ekle\u015ftirebilmeyi planl\u0131yoruz. (\u015euan \u00fczerinde \u00e7al\u0131\u015f\u0131yoruz)<\/p>\n<p>Bu makale i\u00e7erisinde ise <em>ASP.NET Core 2.0<\/em> ile <em>GraphQL<\/em>&#8216;i kullanarak, sorgulama i\u015flemlerini efficient bir \u015fekilde nas\u0131l ger\u00e7ekle\u015ftirebiliriz konusuna, ara\u015ft\u0131rmalar\u0131m s\u0131ras\u0131nda edinebildi\u011fim bilgiler do\u011frultusunda de\u011finmeye \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\n<h5>Peki, Neden GraphQL?<\/h5>\n<p><a href=\"\/wp-content\/uploads\/2017\/07\/graphQL.png\"><img decoding=\"async\" class=\"aligncenter wp-image-1739 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/07\/graphQL.png\" alt=\"\" width=\"575\" height=\"201\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL.png 800w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL-300x105.png 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL-768x269.png 768w\" data-sizes=\"(max-width: 575px) 100vw, 575px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 575px; --smush-placeholder-aspect-ratio: 575\/201;\" \/><\/a><\/p>\n<p>Neden <em>GraphQL<\/em> sorusuna ge\u00e7meden \u00f6nce, bir konuya de\u011finmek istiyorum. Bir \u00e7ok ki\u015fi\u00a0<em>REST<\/em>&#8216;in \u00f6lece\u011fi ve <em>GraphQL<\/em>&#8216;in ise yeni gelecek oldu\u011fundan bahsediyor. Ben \u015fahsen bu fikre kat\u0131lm\u0131yorum. <em>REST<\/em> ve <em>GraphQL<\/em>&#8216;in birbirleri ile kar\u0131\u015ft\u0131r\u0131lmamas\u0131 gerekti\u011fi d\u00fc\u015f\u00fcncesindeyim.<\/p>\n<p>\u0130lk olarak hem\u00a0<em>REST<\/em> hem de <em>GraphQL<\/em>&#8216;in bir arada kullan\u0131m\u0131 m\u00fcmk\u00fcnd\u00fcr. Ayr\u0131ca <em>GraphQL\u00a0<\/em><strong>do\u011fru zaman<\/strong> ve <strong>do\u011fru ihtiya\u00e7lar<\/strong> kar\u015f\u0131s\u0131nda kullan\u0131ld\u0131\u011f\u0131nda,\u00a0veri eri\u015fimi (\u00f6zellikle mobile taraf\u0131 i\u00e7in) ve querying konusunda client&#8217;lar i\u00e7in olduk\u00e7a esneklik sa\u011flamaktad\u0131r.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/11\/graphql-rest.png\"><img decoding=\"async\" class=\"aligncenter wp-image-1865 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/11\/graphql-rest.png\" alt=\"\" width=\"527\" height=\"339\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-rest.png 700w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-rest-300x193.png 300w\" data-sizes=\"(max-width: 527px) 100vw, 527px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 527px; --smush-placeholder-aspect-ratio: 527\/339;\" \/><\/a><\/p>\n<p>Peki, neden <em>GraphQL<\/em> k\u0131sm\u0131na \u015f\u00f6yle bir giri\u015f yapay\u0131m. G\u00fcn\u00fcm\u00fcz teknolojisinde mobile uygulamalar\u0131n\u0131n kullan\u0131m oran\u0131n\u0131n, olduk\u00e7a fazla oldu\u011fu ortada. \u00c7al\u0131\u015fm\u0131\u015f oldu\u011fum firmalarda, online kullan\u0131c\u0131lar\u0131n bir \u00e7o\u011funu neredeyse mobile kullan\u0131c\u0131lar olu\u015fturmakta. Development taraf\u0131na bakt\u0131\u011f\u0131m\u0131zda ise uygulamalar\u0131m\u0131z\u0131n building block&#8217;lar\u0131n\u0131 olu\u015fturan <em>API<\/em>&#8216;lar\u0131, hem web hemde mobile taraflar\u0131 i\u00e7in kullanmaktay\u0131z.<\/p>\n<p>\u0130\u015fte tam da bu noktada, \u00f6zellikle mobile taraf\u0131 i\u00e7in baz\u0131\u00a0challenge&#8217;lar ile kar\u015f\u0131la\u015fmaktay\u0131z. \u00c7\u00fcnk\u00fc mobile taraf\u0131 i\u00e7in al\u0131nan data boyutu, pil ve \u015febeke kullan\u0131m\u0131 gibi durumlar b\u00fcy\u00fck \u00f6nem ta\u015f\u0131maktad\u0131r. Genelde bu tarz challenge&#8217;lar\u0131,\u00a0<em>API<\/em>&#8216;lar\u0131n \u00f6n\u00fcne <strong>Gateway API<\/strong>&#8216;lar yazarak aggregation i\u015flemlerini gateway i\u00e7erisinde ger\u00e7ekle\u015ftirip, developer&#8217;\u0131n istedi\u011fi data&#8217;lar\u0131 filtreleyerek alabilmesi ile atlat\u0131r\u0131z. Kula\u011fa ho\u015f gelse de, ne yaz\u0131k ki i\u015f burada bitmiyor. :) Bununla birlikte <em>versiyonlama<\/em>\u00a0ve\u00a0<em>backward compatibility<\/em>\u00a0gibi\u00a0vb. challenge&#8217;larla da kar\u015f\u0131la\u015fmak durumunda kalabiliyoruz.<\/p>\n<p>\u0130\u015fte bu gibi durumlar kar\u015f\u0131s\u0131nda <em>GraphQL<\/em>&#8216;in bizlere sundu\u011fu a\u015fa\u011f\u0131daki gibi baz\u0131 avantajlar bulunmaktad\u0131r.<\/p>\n<ul>\n<li>Client&#8217;a ihtiya\u00e7 duydu\u011fu data&#8217;y\u0131, <strong>tek bir request<\/strong> ile kolayl\u0131kla alabilme imkan\u0131 sunmaktad\u0131r<\/li>\n<li>Aggregation yap\u0131lan <em>API<\/em> gateway&#8217;ler gibi tailored endpoint&#8217;lere olan ihtiyac\u0131 azaltmaktad\u0131r<\/li>\n<li>En \u00f6nemlisi de h\u0131zl\u0131 ve kolay development yapabilme imkan\u0131n\u0131 sunmaktad\u0131r<\/li>\n<\/ul>\n<p>H\u0131zl\u0131 ve kolay development konusundan biraz bahsetmek gerekirse e\u011fer, bir \u00e7ok kurum i\u00e7erisinde development ekipleri k\u00fc\u00e7\u00fck domain&#8217;lere g\u00f6re b\u00f6l\u00fcn\u00fcp, her ekip kendi sorumlulu\u011funun bulundu\u011fu uygulamalar\u0131 geli\u015ftirmektedir. Benim \u00e7al\u0131\u015ft\u0131\u011f\u0131m bir ka\u00e7 firmada bu \u015fekildeydi.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/11\/small-teams.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-1882 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/11\/small-teams.png\" alt=\"\" width=\"377\" height=\"133\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/small-teams.png 377w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/small-teams-300x106.png 300w\" data-sizes=\"(max-width: 377px) 100vw, 377px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 377px; --smush-placeholder-aspect-ratio: 377\/133;\" \/><\/a><\/p>\n<p>D\u00fc\u015f\u00fcnelim, \u00fcr\u00fcn detay sayfas\u0131nda &#8220;<em>1<\/em>&#8221; numaral\u0131 \u00fcr\u00fcn\u00fcn detay bilgilerine ihtiyac\u0131m\u0131z var. Bir\u00a0<em>RESTful<\/em>\u00a0<em>API\u00a0<\/em>i\u00e7erisinde normal \u015fartlarda bu bilgileri &#8220;<em>api\/products\/1<\/em>&#8221; \u015feklinde bir endpoint&#8217;e <em>GET<\/em> iste\u011finde bulunarak, kolayl\u0131kla eri\u015febiliriz. Mobile ekibin ise bu \u00fcr\u00fcn bilgilerinden sadece &#8220;<em>name<\/em>&#8220;, &#8220;<em>description<\/em>&#8221; ve &#8220;<em>price<\/em>&#8221; field&#8217;lar\u0131na ihtiyac\u0131 olup, bunlara ek olarak birde \u00fcr\u00fcn\u00fcn kategori bilgilerine\u00a0de ihtiyac\u0131 oldu\u011funu varsayal\u0131m.<\/p>\n<p>Bu tarz durumlar kar\u015f\u0131s\u0131nda, yapabilece\u011fimiz iki farkl\u0131 se\u00e7enek bulunmaktad\u0131r.<\/p>\n<ol>\n<li>\u0130ki farkl\u0131 request ger\u00e7ekle\u015ftirip, &#8220;roundtrips&#8221; yapmak (S\u00f6z konusu mobile side ve veri kullan\u0131m\u0131 olunca \u00e7ok fazla tercih etmeyiz san\u0131r\u0131m?)<\/li>\n<li>Ve ya bu i\u015flemi tailored bir endpoint olu\u015fturarak ger\u00e7ekle\u015ftirmek<\/li>\n<\/ol>\n<p>Bunlara ek olarak birde her ekibin kendi sprint&#8217;lerini ko\u015ftu\u011funu varsayarsak, mobile ekip bu noktada &#8220;Product&#8221;\u00a0<em>API<\/em>&#8216;\u0131ndan sorumlu ekibin ilgili development&#8217;\u0131 yapmas\u0131n\u0131 da bekleyecektir. H\u0131zla yeni feature&#8217;lar eklemek istedi\u011fimiz bu teknoloji pazar\u0131nda ise, beklemek \u00e7ok da ho\u015f olmayacakt\u0131r, de\u011fil mi?<\/p>\n<p><em>GraphQL <\/em>ile bir <em>API<\/em> tasarland\u0131\u011f\u0131nda ise, mobile ekip di\u011fer ekiplere ba\u011f\u0131ml\u0131 olmadan istedi\u011fi data&#8217;y\u0131 tek bir request ile efficient bir \u015fekilde sorgulayarak alabilmesi, h\u0131zl\u0131 bir \u015fekilde ihtiya\u00e7lar\u0131na g\u00f6re development i\u015flemlerini ger\u00e7ekle\u015ftirebilmesi kolay bir hale gelmektedir.<\/p>\n<p>\u00d6rnek bir <em>GraphQL<\/em> query&#8217;sine bakmak istersek e\u011fer:<\/p>\n<pre class=\"lang:default decode:true\">{\r\n  product(id: 1){\r\n    name\r\n    description\r\n    price\r\n    category{\r\n      id\r\n      name\r\n    }\r\n  }\r\n}<\/pre>\n<p>Yukar\u0131daki gibi single bir query ile istenilen data, client-driven generated bir \u015fekilde kolayl\u0131kla al\u0131nabilmektedir.<\/p>\n<blockquote><p><strong>NOT<\/strong>: Bu i\u015flemleri elbette bir <em>RESTful API<\/em> ile de yapabilmek m\u00fcmk\u00fcnd\u00fcr. (Querying, filtering, sorting, vb&#8230;) Fakat her yeni bir ihtiya\u00e7 kar\u015f\u0131s\u0131nda istenilen feature&#8217;\u0131n, <em>RESTful API<\/em>&#8216;a implemente edilmesi veya client taraf\u0131nda handle edilmesi gerekmektedir. (Roundtrips!)\u00a0<em>GraphQL<\/em> bu noktada \u00f6n plana \u00e7\u0131karken, unutmamal\u0131y\u0131z ki <em>GraphQL<\/em>&#8216;in istenilenleri ger\u00e7ekle\u015ftirebilmesi i\u00e7in ise, do\u011fru bir mapping yap\u0131s\u0131na da sahip olmas\u0131 gerekmektedir.<\/p><\/blockquote>\n<h5>ASP.NET Core 2.0 ile Implementasyon<\/h5>\n<p>Implementasyon a\u015famas\u0131nda ise, \u00f6rnek olarak basit bir &#8220;\u00fcr\u00fcn&#8221; ve &#8220;kategori&#8221; i\u00e7eren bir <em>API<\/em> tasarlayaca\u011f\u0131z.<\/p>\n<p>Bunun i\u00e7in \u00f6ncelikle a\u015fa\u011f\u0131daki komut sat\u0131r\u0131 ile yeni bir <em>ASP.NET Core<\/em>\u00a0&#8220;<strong>webapi&#8221;<\/strong> projesi olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:default decode:true\">mkdir aspnetcoregarphql\r\ncd aspnetcoregarphql\r\ndotnet new webapi<\/pre>\n<p>Projenin olu\u015fturulmas\u0131ndan sonra &#8220;<em>Models<\/em>&#8221; isminde bir klas\u00f6r olu\u015fturarak, &#8220;<em>Category<\/em>&#8221; ve &#8220;<em>Product<\/em>&#8221; model&#8217;lerini burada tan\u0131mlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Models\r\n{\r\n    public class Category\r\n    {\r\n        public int Id { get; set; }\r\n        public string Name { get; set; }\r\n\r\n        List&lt;Product&gt; Products { get; set; }\r\n    }\r\n}<\/pre>\n<pre class=\"marking:false lang:c# decode:true\">namespace aspnetcoregraphql.Models\r\n{\r\n    public class Product\r\n    {\r\n        public int Id { get; set; }\r\n        public int CategoryId { get; set; }\r\n        public string Name { get; set; }\r\n        public string Description { get; set; }\r\n        public double Price { get; set; }\r\n\r\n        Category Category { get; set;}\r\n    }\r\n}<\/pre>\n<p>Modelleri tan\u0131mlaman\u0131n ard\u0131ndan &#8220;<em>Data<\/em>&#8221; isimli bir klas\u00f6r daha olu\u015ftural\u0131m. \u0130\u00e7erisinde ise &#8220;<em>ICategoryRepository<\/em>&#8221; ve &#8220;<em>IProductRepository<\/em>&#8221; interface&#8217;lerini a\u015fa\u011f\u0131daki gibi olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Data\r\n{\r\n    public interface ICategoryRepository\r\n    {\r\n        Task&lt;List&lt;Category&gt;&gt; CategoriesAsync();\r\n        Task&lt;Category&gt; GetCategoryAsync(int id);\r\n    }\r\n}<\/pre>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Data\r\n{\r\n    public interface IProductRepository\r\n    {\r\n        Task&lt;List&lt;Product&gt;&gt; GetProductsAsync();\r\n        Task&lt;List&lt;Product&gt;&gt; GetProductsWithByCategoryIdAsync(int categoryId);\r\n        Task&lt;Product&gt; GetProductAsync(int id);\r\n    }\r\n}<\/pre>\n<p>Bu interface&#8217;lerin implementasyonlar\u0131n\u0131 ise, test data&#8217;lar\u0131 ile birlikte a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirelim.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Data\r\n{\r\n    public class CategoryRepository : ICategoryRepository\r\n    {\r\n        private List&lt;Category&gt; _categories;\r\n\r\n        public CategoryRepository()\r\n        {\r\n            _categories = new List&lt;Category&gt;{\r\n                new Category()\r\n                {\r\n                    Id = 1,\r\n                    Name = \"Computers\"\r\n                },\r\n                new Category()\r\n                {\r\n                    Id = 2,\r\n                    Name = \"Mobile Phones\"\r\n                }\r\n            };\r\n        }\r\n\r\n        public Task&lt;List&lt;Category&gt;&gt; CategoriesAsync()\r\n        {\r\n            return Task.FromResult(_categories);\r\n        }\r\n\r\n        public Task&lt;Category&gt; GetCategoryAsync(int id)\r\n        {\r\n            return Task.FromResult(_categories.FirstOrDefault(x =&gt; x.Id == id));\r\n        }\r\n    }\r\n}<\/pre>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Data\r\n{\r\n    public class ProductRepository : IProductRepository\r\n    {\r\n        private List&lt;Product&gt; _products;\r\n\r\n        public ProductRepository()\r\n        {\r\n            _products = new List&lt;Product&gt;{\r\n                new Product()\r\n                {\r\n                    Id = 1,\r\n                    CategoryId = 1,\r\n                    Name = \"Apple Macbook Pro 2016\",\r\n                    Description = \"Touchbar, 3.2GHZ\",\r\n                    Price = 5000\r\n                },\r\n                new Product()\r\n                {\r\n                    Id = 2,\r\n                    CategoryId = 1,\r\n                    Name = \"Apple Macbook Air\",\r\n                    Description = \"2.3GHZ 8GB RAM\",\r\n                    Price = 2000\r\n                },\r\n                new Product()\r\n                {\r\n                    Id = 3,\r\n                    CategoryId = 1,\r\n                    Name = \"Dell XPS 13\",\r\n                    Description = \"3.3GHZ 12GB RAM\",\r\n                    Price = 4000\r\n                }\r\n            };\r\n        }\r\n\r\n        public Task&lt;Product&gt; GetProductAsync(int id)\r\n        {\r\n            return Task.FromResult(_products.FirstOrDefault(x =&gt; x.Id == id));\r\n        }\r\n\r\n        public Task&lt;List&lt;Product&gt;&gt; GetProductsAsync()\r\n        {\r\n            return Task.FromResult(_products);\r\n        }\r\n       \r\n        public Task&lt;List&lt;Product&gt;&gt; GetProductsWithByCategoryIdAsync(int categoryId)\r\n        {\r\n            return Task.FromResult(_products.Where(x =&gt; x.CategoryId == categoryId).ToList());\r\n        }\r\n    }\r\n}<\/pre>\n<p>Model ve repository&#8217;ler haz\u0131r oldu\u011funa g\u00f6re, art\u0131k <strong>GraphQL<\/strong>&#8216;in <em>.NET<\/em> client&#8217;\u0131n\u0131 implemente etmeye ba\u015flayabiliriz.<\/p>\n<p>Bunun i\u00e7in \u00f6ncelikle a\u015fa\u011f\u0131daki komutu kullanarak, projemize <em>GraphQL<\/em> paketini <em>NuGet<\/em> \u00fczerinden dahil edelim.<\/p>\n<pre class=\"lang:default decode:true\">dotnet add package GraphQL<\/pre>\n<p>Paketi projemize ekledikten sonra, ilk olarak <strong>GraphQL Object Type<\/strong>&#8216;lar\u0131n\u0131 tan\u0131mlamaya ba\u015flayal\u0131m.\u00a0 <em>Object type<\/em>&#8216;lar\u0131 ve <em>field&#8217;<\/em>lar <em>GraphQL<\/em> schema&#8217;s\u0131n\u0131n en temel bile\u015fenlerini olu\u015fturmaktad\u0131r. Yani, olu\u015fturaca\u011f\u0131m\u0131z servis \u00fczerinden hangi objeleri alabilece\u011fimizi ve hangi field&#8217;lara sahip oldu\u011funu belirtmektedir.<\/p>\n<p>Bu \u00f6n bilginin ard\u0131ndan &#8220;<em>Models<\/em>&#8221; klas\u00f6r\u00fc i\u00e7erisinde, &#8220;<em>CategoryType<\/em>&#8221; ve &#8220;<em>ProductType<\/em>&#8221; class&#8217;lar\u0131n\u0131 da a\u015fa\u011f\u0131daki gibi olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Models\r\n{\r\n    public class CategoryType : ObjectGraphType&lt;Category&gt;\r\n    {\r\n        public CategoryType(IProductRepository productRepository)\r\n        {\r\n            Field(x =&gt; x.Id).Description(\"Category id.\");\r\n            Field(x =&gt; x.Name, nullable: true).Description(\"Category name.\");\r\n\r\n            Field&lt;ListGraphType&lt;ProductType&gt;&gt;(\r\n                \"products\", \r\n                resolve: context =&gt; productRepository.GetProductsWithByCategoryIdAsync(context.Source.Id).Result.ToList()\r\n            );\r\n        }\r\n    }\r\n}<\/pre>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Models\r\n{\r\n    public class ProductType : ObjectGraphType&lt;Product&gt;\r\n    {\r\n        public ProductType(ICategoryRepository categoryRepository)\r\n        {\r\n            Field(x =&gt; x.Id).Description(\"Product id.\");\r\n            Field(x =&gt; x.Name).Description(\"Product name.\");\r\n            Field(x =&gt; x.Description, nullable: true).Description(\"Product description.\");\r\n            Field(x =&gt; x.Price).Description(\"Product price.\");\r\n\r\n            Field&lt;CategoryType&gt;(\r\n                \"category\", \r\n                resolve: context =&gt; categoryRepository.GetCategoryAsync(context.Source.CategoryId).Result\r\n             );\r\n        }\r\n    }\r\n}<\/pre>\n<p>Dikkat edersek her iki class da, &#8220;<em>ObjectGraphType<\/em>&#8221; class&#8217;\u0131ndan t\u00fcretilmektedir. Sonras\u0131nda ise constructor i\u00e7erisinden <em>GraphQL<\/em> paketinin fluent method&#8217;lar\u0131n\u0131 kullanarak, hangi field&#8217;lara sahip olmas\u0131 gerekti\u011fini expression&#8217;lar ile tan\u0131mlad\u0131k. Ard\u0131ndan relation field&#8217;lar\u0131 i\u00e7in ise resolve function&#8217;lar\u0131n\u0131 yazd\u0131k.<\/p>\n<p>\u015eimdi query i\u015flemleri i\u00e7in kullanacak oldu\u011fumuz root type&#8217;\u0131 olu\u015fturaca\u011f\u0131z. Bunun i\u00e7in &#8220;<em>EasyStoreQuery<\/em>&#8221; isminde yeni bir class tan\u0131mlayal\u0131m ve a\u015fa\u011f\u0131daki gibi kodlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Models\r\n{\r\n    public class EasyStoreQuery : ObjectGraphType\r\n    {\r\n        public EasyStoreQuery(ICategoryRepository categoryRepository, IProductRepository productRepository)\r\n        {\r\n            Field&lt;CategoryType&gt;(\r\n                \"category\",\r\n                arguments: new QueryArguments(\r\n                    new QueryArgument&lt;NonNullGraphType&lt;IntGraphType&gt;&gt; {Name = \"id\", Description = \"Category id\"}\r\n                ),\r\n                resolve: context =&gt; categoryRepository.GetCategoryAsync(context.GetArgument&lt;int&gt;(\"id\")).Result\r\n            );\r\n\r\n            Field&lt;ProductType&gt;(\r\n                \"product\",\r\n                arguments: new QueryArguments(\r\n                    new QueryArgument&lt;NonNullGraphType&lt;IntGraphType&gt;&gt; {Name = \"id\", Description = \"Product id\"}\r\n                ),\r\n                resolve: context =&gt; productRepository.GetProductAsync(context.GetArgument&lt;int&gt;(\"id\")).Result\r\n            );\r\n        }\r\n    }\r\n}<\/pre>\n<p>&#8220;<em>EasyStoreQuery<\/em>&#8221; root type&#8217;\u0131 i\u00e7erisinde, &#8220;<em>CategoryType<\/em>&#8221; ve &#8220;<em>ProductType<\/em>&#8221; da oldu\u011fu gibi constructor i\u00e7erisinde schema&#8217;y\u0131 configure ettik. Configure i\u015flemi s\u0131ras\u0131nda &#8220;<strong>arguments<\/strong>&#8221; parametresi ile ise, ilgili field&#8217;\u0131n hangi argument&#8217;ler do\u011frultusunda al\u0131nabilece\u011fini belirttik.<\/p>\n<blockquote><p><strong>NOT<\/strong>: &#8220;<em>CategoryType<\/em>&#8220;, &#8220;<em>ProductType<\/em>&#8221; ve &#8220;<em>EasyStoreQuery<\/em>&#8221; i\u00e7erisindeki resolve function&#8217;lar\u0131n\u0131n source&#8217;u olarak &#8220;category&#8221; ve &#8220;product&#8221; repository&#8217;lerini configure etmek yerine, &#8220;category&#8221; ve ya &#8220;product&#8221; i\u00e7in olan ilgili\u00a0<em>REST <\/em>endpoint&#8217;lerini de<em>\u00a0<\/em>configure edebilirdik.<\/p><\/blockquote>\n<p>Art\u0131k d\u0131\u015far\u0131ya expose edecek oldu\u011fumuz data&#8217;m\u0131z\u0131n, structure&#8217;\u0131n\u0131 tan\u0131mlayacak olan schema&#8217;y\u0131 olu\u015fturabiliriz. Bunun i\u00e7in &#8220;<em>EasyStoreSchema<\/em>&#8221; ad\u0131nda bir class daha olu\u015ftural\u0131m ve &#8220;<em>Schema<\/em>&#8221; class&#8217;\u0131ndan t\u00fcreterek, a\u015fa\u011f\u0131daki gibi kodlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Models\r\n{\r\n    public class EasyStoreSchema : Schema\r\n    {\r\n        public EasyStoreSchema(Func&lt;Type, GraphType&gt; resolveType)\r\n            :base(resolveType)\r\n        {\r\n            Query = (EasyStoreQuery)resolveType(typeof(EasyStoreQuery));\r\n        }\r\n    }\r\n}<\/pre>\n<p>Bir schema&#8217;n\u0131n sahip olabilece\u011fi iki adet\u00a0temel type bulunmaktad\u0131r. Bunlardan ilki &#8220;Query&#8221;, di\u011feri ise &#8220;Mutation&#8221; type&#8217;\u0131d\u0131r. Biz ise burada sadece &#8220;Query&#8221; type&#8217;\u0131n\u0131 kulland\u0131k. &#8220;<em>EasyStoreSchema<\/em>&#8221; class&#8217;\u0131n\u0131\u00a0<strong>DI<\/strong> container \u00fczerinden inject ederken, resolve type olarak ise &#8220;<em>EasyStoreQuery<\/em>&#8221; type&#8217;\u0131n\u0131 parametre olarak ge\u00e7ece\u011fiz.<\/p>\n<p>Art\u0131k geriye yapmam\u0131z gereken iki \u015fey kald\u0131. Bunlardan ilki GraphQL endpoint&#8217;ini haz\u0131rlamak, bir di\u011feri de service injection i\u015flemlerini ger\u00e7ekle\u015ftirmek. Endpoint&#8217;i haz\u0131rlamak i\u00e7in \u00f6ncelikle &#8220;<em>Models<\/em>&#8221; klas\u00f6r\u00fc i\u00e7erisinde &#8220;<em>GraphQLQuery<\/em>&#8221; isminde bir request class&#8217;\u0131 olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki gibi tan\u0131mlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Models\r\n{\r\n    public class GraphQLQuery\r\n    {\r\n        public string OperationName { get; set; }\r\n        public string NamedQuery { get; set; }\r\n        public string Query { get; set; }\r\n        public string Variables { get; set; }\r\n    }\r\n}<\/pre>\n<p>Request objesini tan\u0131mlaman\u0131n ard\u0131ndan, &#8220;<em>Controllers<\/em>&#8221; klas\u00f6r\u00fc i\u00e7erisinde ise &#8220;<em>GraphQLController<\/em>&#8221; isminde bir controller class&#8217;\u0131 ekleyerek kodlamaya ba\u015flayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">namespace aspnetcoregraphql.Controllers\r\n{\r\n    [Route(\"graphql\")]\r\n    public class GraphQLController : Controller\r\n    {\r\n        private readonly IDocumentExecuter _documentExecuter;\r\n        private readonly ISchema _schema;\r\n\r\n        public GraphQLController(IDocumentExecuter documentExecuter,ISchema schema)\r\n        {\r\n            _documentExecuter = documentExecuter;\r\n            _schema = schema;\r\n        }\r\n\r\n        [HttpPost]\r\n        public async Task&lt;IActionResult&gt; Post([FromBody]GraphQLQuery query)\r\n        {\r\n            if (query == null) { throw new ArgumentNullException(nameof(query)); }\r\n\r\n            var executionOptions = new ExecutionOptions { Schema = _schema, Query = query.Query };\r\n\r\n            try\r\n            {\r\n                var result = await _documentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false);\r\n\r\n                if (result.Errors?.Count &gt; 0)\r\n                {\r\n                    return BadRequest(result);\r\n                }\r\n\r\n                return Ok(result);\r\n            }\r\n            catch(Exception ex)\r\n            {\r\n                return BadRequest(ex);\r\n            }\r\n        }\r\n    }\r\n}<\/pre>\n<p>\u0130lk olarak &#8220;<em>Route<\/em>&#8221; attribute&#8217;\u00fc ile endpoint&#8217;i belirledik ve ard\u0131ndan &#8220;<em>IDocumentExecuter<\/em>&#8221; ve &#8220;<em>ISchema<\/em>&#8221; interface&#8217;lerinin inject i\u015flemlerini ger\u00e7ekle\u015ftirdik. Bu noktada &#8220;<em>IDocumentExecuter<\/em>&#8220;, &#8220;<em>ExecutionOptions<\/em>&#8221; parametresini execute ederek, client&#8217;\u0131n istemi\u015f oldu\u011fu data&#8217;y\u0131 olu\u015fturacakt\u0131r. Bu noktada, client-driven application development yapabilmek, \u00e7ok da ho\u015f de\u011fil mi?<\/p>\n<p>Art\u0131k geriye sadece dependency injection i\u015flemi kald\u0131. &#8220;<em>Startup<\/em>&#8221; class&#8217;\u0131 i\u00e7erisinde injection i\u015flemlerini a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirelim.<\/p>\n<pre class=\"lang:c# decode:true\">public void ConfigureServices(IServiceCollection services)\r\n{\r\n    services.AddMvc();\r\n\r\n    services.AddScoped&lt;EasyStoreQuery&gt;();   \r\n    services.AddTransient&lt;ICategoryRepository, CategoryRepository&gt;();\r\n    services.AddTransient&lt;IProductRepository, ProductRepository&gt;();   \r\n    services.AddScoped&lt;IDocumentExecuter, DocumentExecuter&gt;();\r\n    services.AddTransient&lt;CategoryType&gt;();\r\n    services.AddTransient&lt;ProductType&gt;();\r\n    var sp = services.BuildServiceProvider();\r\n    services.AddScoped&lt;ISchema&gt;(_ =&gt; new EasyStoreSchema(type =&gt; (GraphType) sp.GetService(type)) {Query = sp.GetService&lt;EasyStoreQuery&gt;()});\r\n}<\/pre>\n<p>\u0130\u015fte hepsi bu kadar.<\/p>\n<p>\u015eimdi terminal \u00fczerinden &#8220;<em>dotnet run<\/em>&#8221; komutunu \u00e7al\u0131\u015ft\u0131rarak, bir ka\u00e7 test yapabiliriz.<\/p>\n<blockquote><p><strong>NOT<\/strong>: Ben test i\u015flemleri i\u00e7in &#8220;<em>Postman<\/em>&#8221; kullanaca\u011f\u0131m.<\/p><\/blockquote>\n<p>A\u015fa\u011f\u0131daki sorguyu <em>GraphQL<\/em> endpoint&#8217;ine, <strong>POST<\/strong>\u00a0olarak g\u00f6nderelim ve sonucunu g\u00f6relim.<\/p>\n<pre class=\"lang:default decode:true\">{ \r\n \"query\":\r\n  \"query{\r\n     category(id:1){\r\n       id \r\n       name\r\n     }\r\n   }\"\r\n}<\/pre>\n<p>Response&#8217;a bakt\u0131\u011f\u0131m\u0131zda ise a\u015fa\u011f\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi, &#8220;<em>1<\/em>&#8221; numaral\u0131 kategoriye ait &#8220;<em>id<\/em>&#8221; ve &#8220;<em>name<\/em>&#8221; field&#8217;lar\u0131 gelmi\u015ftir.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-1843 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore.png\" alt=\"\" width=\"2048\" height=\"1612\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore.png 2048w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-300x236.png 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-768x605.png 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-1024x806.png 1024w\" data-sizes=\"(max-width: 2048px) 100vw, 2048px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2048px; --smush-placeholder-aspect-ratio: 2048\/1612;\" \/><\/a>Peki ya bu kategoriye ait \u00fcr\u00fcnleri, &#8220;<em>id<\/em>&#8220;, &#8220;<em>name<\/em>&#8220;, ve &#8220;<em>price<\/em>&#8221; field&#8217;lar\u0131 ile gelmesini de istiyorsak, bu durumda ne olacak? Gayet basit. Tek yapmam\u0131z gereken, sorgumuzu a\u015fa\u011f\u0131daki gibi g\u00fcncellemek olacakt\u0131r.<\/p>\n<pre class=\"lang:default decode:true \">{ \r\n \"query\":\r\n  \"query{\r\n     category(id:1){\r\n       id \r\n       name\r\n       products{\r\n       \tid\r\n       \tname\r\n       \tprice\r\n       }\r\n     }\r\n   }\"\r\n}<\/pre>\n<p>Sonucu ise a\u015fa\u011f\u0131daki gibi ortada.<\/p>\n<h5><a href=\"\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-sample.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-1846 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-sample.png\" alt=\"\" width=\"2048\" height=\"2158\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-sample.png 2048w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-sample-285x300.png 285w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-sample-768x809.png 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/11\/graphql-aspnetcore-sample-972x1024.png 972w\" data-sizes=\"(max-width: 2048px) 100vw, 2048px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2048px; --smush-placeholder-aspect-ratio: 2048\/2158;\" \/><\/a>Sonu\u00e7<\/h5>\n<p><em>GraphQL<\/em> ile <em>PoC<\/em> yaparken ger\u00e7ekten \u00e7ok keyif ald\u0131m. Bu konudaki benim fikrim ise, e\u011fer database schema&#8217;m\u0131z ve ya <em>API<\/em> design&#8217;lar\u0131m\u0131z resource olarak kullan\u0131lmaya uygun ise, <em>GraphQL&#8217;<\/em>i implemente etmek\u00a0\u00f6zellikle <strong>client-driven application development<\/strong> i\u00e7in do\u011fru bir tercih olacakt\u0131r. Ayr\u0131ca GraphQL client&#8217;a sadece istedi\u011fi \u00f6l\u00e7\u00fcde data&#8217;y\u0131 verebilmesiyle beraber, server ile client aras\u0131ndaki veri boyutunun k\u00fc\u00e7\u00fclmesini de sa\u011flamaktad\u0131r.<\/p>\n<p>\u00d6rnek projeye ise buradan eri\u015febilirsiniz:\u00a0<a href=\"https:\/\/github.com\/GokGokalp\/ASP.NET-Core-2.0-GraphQL-Sample\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/GokGokalp\/ASP.NET-Core-2.0-GraphQL-Sample<\/a><\/p>\n<h5>Referanslar<\/h5>\n<blockquote><p>https:\/\/github.com\/graphql-dotnet\/graphql-dotnet<\/p>\n<p>http:\/\/graphql.org\/learn\/<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Merhaba arkada\u015flar. Bir s\u00fcredir yeni bir makale yazmaya f\u0131rsat bulamad\u0131m. Hatta bu makalenin bir k\u0131sm\u0131n\u0131 ise A\u011fustos ay\u0131nda yazm\u0131\u015ft\u0131m, fakat bir t\u00fcrl\u00fc tamamlayamam\u0131\u015ft\u0131m. :) Buldu\u011fum ilk f\u0131rsatta ise tamamlamay\u0131 ba\u015fard\u0131m. Herneyse, san\u0131r\u0131m\u00a0GraphQL\u00a0(ayr\u0131ca Asp.NET Core 2.0),\u00a0veri eri\u015fimi ve sorgulama \u00fczerine son d\u00f6nemlerin en pop\u00fcler konular\u0131 aras\u0131ndad\u0131r.&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">GraphQL&#8217;e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":1739,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[417,449],"tags":[463,461,458,459,462],"class_list":["post-1736","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-asp-net-core","category-graphql","tag-aspnet-core-2-0-graphql-implementation","tag-aspnet-core-graphql","tag-graphql","tag-graphql-nedir","tag-graphql-ornek-proje","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":true,"content":true,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GraphQL&#039;e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GraphQL&#039;e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-22T16:26:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-12-11T18:46:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL.png\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"280\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\"GraphQL&#8217;e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak\",\"datePublished\":\"2017-11-22T16:26:00+00:00\",\"dateModified\":\"2017-12-11T18:46:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/\"},\"wordCount\":3263,\"commentCount\":22,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/graphQL.png\",\"keywords\":[\"asp.net core 2.0 graphql implementation\",\"asp.net core graphql\",\"graphql\",\"graphql nedir\",\"graphql \u00f6rnek proje\"],\"articleSection\":[\"ASP.NET Core\",\"GraphQL\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/\",\"name\":\"GraphQL'e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/graphQL.png\",\"datePublished\":\"2017-11-22T16:26:00+00:00\",\"dateModified\":\"2017-12-11T18:46:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#primaryimage\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/graphQL.png\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/07\\\/graphQL.png\",\"width\":800,\"height\":280},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introduction to GraphQL and Designing Simple Query API with ASP.NET Core 2.0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"GraphQL'e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak - G\u00f6khan G\u00f6kalp","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/","og_locale":"tr_TR","og_type":"article","og_title":"GraphQL'e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2017-11-22T16:26:00+00:00","article_modified_time":"2017-12-11T18:46:35+00:00","og_image":[{"width":800,"height":280,"url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL.png","type":"image\/png"}],"author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"23 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":"GraphQL&#8217;e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak","datePublished":"2017-11-22T16:26:00+00:00","dateModified":"2017-12-11T18:46:35+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/"},"wordCount":3263,"commentCount":22,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL.png","keywords":["asp.net core 2.0 graphql implementation","asp.net core graphql","graphql","graphql nedir","graphql \u00f6rnek proje"],"articleSection":["ASP.NET Core","GraphQL"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/","url":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/","name":"GraphQL'e Giri\u015f ve ASP.NET Core 2.0 ile Basit Bir Query API Tasarlamak - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#primaryimage"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL.png","datePublished":"2017-11-22T16:26:00+00:00","dateModified":"2017-12-11T18:46:35+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#primaryimage","url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL.png","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/07\/graphQL.png","width":800,"height":280},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/introduction-to-graphql-and-designing-simple-query-api-with-aspnet-core-2-0\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Introduction to GraphQL and Designing Simple Query API with ASP.NET Core 2.0"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/1736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=1736"}],"version-history":[{"count":70,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/1736\/revisions"}],"predecessor-version":[{"id":2003,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/1736\/revisions\/2003"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media\/1739"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=1736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=1736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=1736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}