# Asp.Net Core Api İle Graphql Projesi Oluşturmak

Bu yazı dizimiz de Asp.Net Core Api teması kullanarak graphql ile sql server veritabanina nasıl bağlantı kurabileceğimizi göreceğiz.

Kaynak Kodlara aşağıdaki repodan ulaşabilirsiniz.

{% embed url="<https://github.com/cagdaskarademir/tutorial-aspnetcore-graphql-sqlserver>" %}

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LpxbmvhpphwXxY5kCcO%2F-LpxcKpxyiMKsnleKT4K%2Fimage.png?alt=media\&token=977a7883-e157-4d4c-adbe-b05415ca747b)

## Makalenin Amacı

.Net Core Web Api ve GraphQL kullanarak SQL Server veritabanında select  işlemlerinin nasıl yapılacağını tecrübe edineceğiz.&#x20;

## Bilmeniz veya Öğrenmeniz Gereken Terimler

{% hint style="info" %}
Aşağıdaki terimler hakkında bilgi sahibi olmalısınız.
{% endhint %}

1. .Net Core Web Api Nedir?
2. .Net Core Web Api Projesi Nasıl Oluşturulur?
3. GraphQL Nedir?&#x20;
4. ObjectGraphType Nedir?&#x20;
5. Dapper Nedir?
6. SqlKata Nedir?

## Kullanılan Yan Teknolojiler

Orm tool olarak Dapper altyapısı kullanılarak hızlı bir şekilde sql kodu yazabileceğimiz SqlKata Query Generater kütüphanesini kullanacağız.

SqlKata kütüphanesine <https://sqlkata.com/> linki üzerinden erişebilirsiniz.&#x20;

Dökümantasyon ve örnekler için <https://sqlkata.com/docs> adresini ziyaret etmenizi öneririm.

## Katmanların Oluşturulması

### Web Projesinin Oluşturulması <a href="#web-projesinin-olusturulmasi" id="web-projesinin-olusturulmasi"></a>

a[sp.net](http://asp.net/) web api projesi oluşturuyoruz.‌

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-LvvZwrsWwDmI2NoQMII%2Fimage.png?alt=media\&token=8fcf023e-be90-4512-a817-95eb1e79283e)

Web Projemize aşağıdaki kütüphaneleri ekliyoruz.

```csharp
<PackageReference Include="GraphQL" Version="2.4.0" />
```

### Entity Projesinin Oluşturulması <a href="#entity-projesinin-olusturulmasi" id="entity-projesinin-olusturulmasi"></a>

Tablo setlerimizi yöneteceğimiz Entity katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_7UwVXCROxr743gO%2Fimage.png?alt=media\&token=e77addac-19dc-4cb2-9f9f-a813931ecd7d)

Referans Projesi olarak aşağıdaki projeyi ekliyoruz.

```csharp
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Common\CK.Tutorial.GraphQlApi.Common.csproj" />
```

### Common Katmanının Oluşturulması <a href="#common-katmaninin-olusturulmasi" id="common-katmaninin-olusturulmasi"></a>

‌Tüm katmanlarda kullanacağımız enum, const ve helper sınıfları için Common katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_NMdpTN8H4mQkyzV%2Fimage.png?alt=media\&token=553d2f4c-16ce-4ec9-b5cf-e711b4686cc3)

Projemize Newtonsoft.Json kütüphanesini ekliyoruz.

```csharp
 <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
```

### Business Katmanının Oluşturulması <a href="#business-katmaninin-olusturulmasi" id="business-katmaninin-olusturulmasi"></a>

İş süreçlerini kontrol edebileceğimiz Business katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_TjOf6PWCXj6Up3f%2Fimage.png?alt=media\&token=4118be7c-b8f0-4683-996e-41bf041b4cac)

### Model Katmanının Oluşturulması <a href="#model-katmaninin-olusturulmasi" id="model-katmaninin-olusturulmasi"></a>

Verilerimizi transfer edeceğimiz Model katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv__Z7Qr_XSjJSx8Bb%2Fimage.png?alt=media\&token=e0500878-e14d-42e4-a860-dbb9e3d2177c)

Referans Projesi olarak aşağıdaki projeyi ekliyoruz.

```csharp
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Common\CK.Tutorial.GraphQlApi.Common.csproj" />
```

### Repository Katmanının Oluşturulması <a href="#repository-katmaninin-olusturulmasi" id="repository-katmaninin-olusturulmasi"></a>

Veritabanı işlemlerini yönetebildiğimiz data katmanımız olan Repository katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_hcrvDYk2uyqwKkJ%2Fimage.png?alt=media\&token=7b1f4b87-c152-4bb7-8c79-c537d64b3b6d)

Repository katmanına aşağıdaki referansları ekleyin.

```aspnet
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
<PackageReference Include="SqlKata" Version="1.1.7" />
<PackageReference Include="SqlKata.Execution" Version="1.1.7" />
```

Referans projesini olarak aşağıdaki kütüphaneleri ekliyoruz.

{% code title="CK.Tutorial.GraphQlApi.Repository.csproj" %}

```aspnet
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Common\CK.Tutorial.GraphQlApi.Common.csproj" />
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Entity\CK.Tutorial.GraphQlApi.Entity.csproj" />
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Model\CK.Tutorial.GraphQlApi.Model.csproj" />
```

{% endcode %}

## Common Layer

### Extension Dosyalarının Oluşturulması

Array değişkenlerimize yardımcı olması için aşağıdaki extension'ı yazıyoruz.

```csharp
using System.Linq;

namespace CK.Tutorial.GraphQlApi.Common.Extension
{
    public static class ArrayExtension
    {
        public static bool AnyItem(this string[] value)
        {
            return value != null && value.Any();
        }
    }
}
```

Primitive değişkenlerimize yardımcı olmak için aşağıdaki extension'ı yazıyoruz.

```csharp
using System;

namespace CK.Tutorial.GraphQlApi.Common.Extension
{
    public static class PrimitiveExtension
    {
        public static bool IsNotNullOrEmpty(this string value)
        {
            return !string.IsNullOrEmpty(value);
        }

        public static bool IsNotNull(this bool? value)
        {
            return value != null;
        }
        
        public static bool IsTrue(this bool? value)
        {
            return value != null && value == true;
        }
        
        public static byte ConvertToByte(this bool? value)
        {
            if (value ==null )
            {
                throw new ArgumentException("Boolean Item must be convertible");
            }

            return (byte) (value.Value ? 1 : 0);
        }
    }
}
```

### Common Model Dosyalarının Oluşturulması

Kullanıcılardan parametrik olarak alacağımız veriler için base request sınıfı oluşturuyoruz.

```csharp
namespace CK.Tutorial.GraphQlApi.Common.Model
{
    public class RequestBase
    {
        public int DefaultPage { get; } = 1;
        public int DefaultPageSize { get; } = 10;
        public string[] Columns { get; set; }
        public int? PageSize { get; set; }
        public int? Page { get; set; }
    }
}
```

GraphQL için aşağıdaki model dosyamızı oluşturuyoruz.

```csharp
using System.Text;

namespace CK.Tutorial.GraphQlApi.Common.Model
{
    public class GraphQlQuery
    {
        public string OperationName { get; set; }
        public string NamedQuery { get; set; }
        public string Query { get; set; }
        public string Variables { get; set; }

        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.AppendLine();
            if (!string.IsNullOrWhiteSpace(OperationName)) builder.AppendLine($"OperationName = {OperationName}");
            if (!string.IsNullOrWhiteSpace(NamedQuery)) builder.AppendLine($"NamedQuery = {NamedQuery}");
            if (!string.IsNullOrWhiteSpace(Query)) builder.AppendLine($"Query = {Query}");
            if (!string.IsNullOrWhiteSpace(Variables)) builder.AppendLine($"Variables = {Variables}");

            return builder.ToString();
        }
    }
}
```

## Entity Katmanı

### Company Entity

```csharp
namespace CK.Tutorial.GraphQlApi.Entity
{
    public class Company
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool IsActive { get; set; }
    }
}
```

### Product Entity

```csharp
using CK.Tutorial.GraphQlApi.Common.Enum;

namespace CK.Tutorial.GraphQlApi.Entity
{
    public class Product
    {
        public int Id { get; set; }
        public int CompanyId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public int ProductTypeId { get; set; }
        public Status Status { get; set; }
    }
}
```

## Model Katmanı

### Search Company Database Transfer Object&#x20;

Kullanıcıdan aldığımız verileri alt katmanlara aşağıdaki veri deseniyle göndereceğiz.

```csharp
using CK.Tutorial.GraphQlApi.Common.Model;

namespace CK.Tutorial.GraphQlApi.Model.Request
{
    public class SearchCompany : RequestBase
    {
        public int? Id { get; set; }
        public string Name { get; set; }
        public bool? IsActive { get; set; }
    }
}
```

## Repository Katmanı

### ‌IRepositoryBase Interface Oluşturulması

Repository sınıflarımız için generic base bir Interface tanımlıyoruz.

{% code title="IRepository.cs" %}

```csharp
‌using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public interface IRepositoryBase<TEntity>
    {
        QueryFactory QueryFactory { get; }
    }
}
```

{% endcode %}

## RepositoryBase Sınıfının Oluşturulması <a href="#repositorybase-sinifinin-olusturulmasi" id="repositorybase-sinifinin-olusturulmasi"></a>

Oluşturacağımız Entity Repository'leri için RepositoryBase sınıfını, IRepositoryBase interface'i üzerinden oluşturuyoruz.

{% code title="RepositoryBase.cs" %}

```csharp
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public class RepositoryBase<TEntity> : IRepositoryBase<TEntity>
    {
        public RepositoryBase(QueryFactory queryFactory)
        {
            QueryFactory = queryFactory;
        }

        public QueryFactory QueryFactory { get; set; }
    }
}
```

{% endcode %}

### ‌ICompanyRepository Interface Oluşturulması

{% code title="ICompanyRepository.cs" %}

```csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public interface ICompanyRepository
    {
        Task<IEnumerable<Company>> GetCompanies(SearchCompany request);
        Task<Company> GetCompany(SearchCompany request);
    }
}
```

{% endcode %}

### CompanyRepository Sınıfının Oluşturulması

{% code title="CompanyRepository.cs" %}

```csharp
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Common.Extension;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public class CompanyRepository : RepositoryBase<Company>, ICompanyRepository
    {
        private readonly QueryFactory _queryFactory;
        private const string TableName = "Company";

        public CompanyRepository(QueryFactory queryFactory) : base(queryFactory)
        {
            _queryFactory = queryFactory;
        }

        public async Task<IEnumerable<Company>> GetCompanies(SearchCompany request)
        {
            var query = _queryFactory
                .Query(TableName)
                .When(request.Columns.AnyItem(),
                    q => q.Select(request.Columns))
                .When(request.IsActive.IsNotNull(), q => q.Where("IsActive", request.IsActive.ConvertToByte()))
                .OrderBy("Id")
                .ForPage(request.Page ?? request.DefaultPage, request.PageSize ?? request.DefaultPageSize)
                .GetAsync<Company>();

            return await query.ConfigureAwait(false);
        }

        public async Task<Company> GetCompany(SearchCompany request)
        {
            var query = _queryFactory
                .Query(TableName)
                .When(request.Columns.AnyItem(),
                    q => q.Select(request.Columns))
                .When(request.Id.HasValue, q => q.Where("Id", request.Id))
                .When(request.Name.IsNotNullOrEmpty(), q => q.WhereContains("Name", request.Name))
                .When(request.IsActive.IsNotNull(), q => q.Where("IsActive", request.IsActive.ConvertToByte()))
                .OrderBy("Id")
                .FirstOrDefaultAsync<Company>();

            return await query.ConfigureAwait(false);
        }
    }
}

```

{% endcode %}

## Business Katmanı

‌Company Entity'sinin iş süreçlerini yazmak için ICompanyService adında bir interface oluşturuyoruz.&#x20;

Şimdilik iki tane metod yazacağız.&#x20;

### ICompanyService Oluşturulması

{% code title="ICompanyService.cs" %}

```csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Business
{
    public interface ICompanyService
    {
        Task<IEnumerable<Company>> GetCompanies(SearchCompany request);
        Task<Company> GetCompany(SearchCompany request);
    }
}
```

{% endcode %}

### CompanyService Sınıfının Oluşturulması

ICompanyService üzerinden CompanyService adında yeni bir sınıf oluşturuyoruz.

{% code title="CompanyService.cs" %}

```csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using CK.Tutorial.GraphQlApi.Repository;

namespace CK.Tutorial.GraphQlApi.Business
{
    public class CompanyService : ICompanyService
    {
        private readonly ICompanyRepository _companyRepository;

        public CompanyService(ICompanyRepository companyRepository)
        {
            _companyRepository = companyRepository;
        }
        
        public Task<IEnumerable<Company>> GetCompanies(SearchCompany request)
        {
            return _companyRepository.GetCompanies(request);
        }

        public Task<Company> GetCompany(SearchCompany request)
        {
            return _companyRepository.GetCompany(request);
        }
    }
}
```

{% endcode %}

## Web - Graphql Katmanı

GraphQL Schema adını verdiğimiz referans bir root sınıfından oluşur.&#x20;

Schema sınıfına Resolver bir tane QUERY referans gösterilir..

Query dosyaları ise GraphType'lardan beslenerek dinamik sorgular oluşturacağımız bir yapı kurmamızı sağlar.

Kısacası Schema > Query > GraphTypes olarak tanımlayabiliriz.

Retail adında bir tane Root Schema sınıfımızı aşağıdaki gibi tanımlıyoruz.

RetailSchema sınıfının TutorialQuery adında bir sorgulama sınıfını çözümlediğini bildiriyoruz.

### Schema Sınıfının Oluşturulması

{% code title="RetailSchema.cs" %}

```csharp
using CK.Tutorial.GraphQlApi.Web.Query;
using GraphQL;

namespace CK.Tutorial.GraphQlApi.Web.Schema
{
    public class RetailSchema : GraphQL.Types.Schema
    {
        public RetailSchema(IDependencyResolver resolver) : base(resolver)
        {
            Query = resolver.Resolve<TutorialQuery>();
        }
    }
}
```

{% endcode %}

### Company Graph Type Sınıfının Oluşturulması

Entity sınıflarımızın field alanlarını kullanarak graphql için sorgulanabilir tipler oluşturuyoruz.

Aşağıdaki örneğimizde Company Entity dosyasımızı referans göstermiş ve field alanları için Type tanımlamalarını yapmış olduğumuzu göreceksiniz.&#x20;

Örneğin Name alanı için ikinci parametre olan IsNullable alanını True vererek, bu field için null alabilen bir field düzenlemiş olduk. Diğer override parametrelerini kullanarak TYPE tipinide değiştirmeniz veya belirtmeniz mümkündür.

{% code title="CompanyGraphType.cs" %}

```csharp
using System;
using CK.Tutorial.GraphQlApi.Business;
using CK.Tutorial.GraphQlApi.Entity;
using GraphQL.Types;

namespace CK.Tutorial.GraphQlApi.Web.Types
{
    public class CompanyGraphType : ObjectGraphType<Company>
    {
        public CompanyGraphType()
        {
            Name = "Company";
            Field(x => x.Id).Description("Şirket Benzersiz No");
            Field(x => x.Name, true).Description("Şirket Adı");
            Field(x => x.IsActive, true).Description("Şirket Aktif mi?");
        }
    }
}
```

{% endcode %}

## TutorialQuery Sınıfının Oluşturulması

Bu örneğimizde 2 tane sorgulama endpoint'i oluşturacağız.

Birinci endpoint; "company" adını verdiğimiz, CompanyGraphType kullanarak sorgu yapabileceğimiz,&#x20;

* companyId
* companyName
* isActive

parametrelerinden oluşan ve return type değeri COMPANY entity sınıfımızdır. &#x20;

İkinci endpoint; "companies" adını verdiğimiz ve return tipi List\<Company> olan sınıfımızdır.

{% code title="TutorialQuery.cs" %}

```csharp
using System.Collections.Generic;
using CK.Tutorial.GraphQlApi.Business;
using CK.Tutorial.GraphQlApi.Model.Request;
using CK.Tutorial.GraphQlApi.Web.Extensions;
using CK.Tutorial.GraphQlApi.Web.Types;
using GraphQL.Types;

namespace CK.Tutorial.GraphQlApi.Web.Query
{
    public class TutorialQuery : ObjectGraphType
    {
        public TutorialQuery(ICompanyService companyService)
        {
            #region Company

            Field<CompanyGraphType>(
                name: "company",
                arguments: new QueryArguments(new List<QueryArgument>
                {
                    new QueryArgument<IntGraphType>
                    {
                        Name = "companyId"
                    },
                    new QueryArgument<StringGraphType>
                    {
                        Name = "companyName"
                    },
                    new QueryArgument<BooleanGraphType>
                    {
                        Name = "isActive"
                    }
                }),
                resolve: delegate (ResolveFieldContext<object> context)
                {
                    var columns = context.GetMainSelectedFields();

                    var companyId = context.GetArgument<int?>("companyId");
                    var companyName = context.GetArgument<string>("companyName");
                    var isActive = context.GetArgument<bool?>("isActive");

                    var request = new SearchCompany
                    {
                        Id = companyId,
                        Name = companyName,
                        IsActive = isActive,
                        Columns = columns
                    };
                    return companyService.GetCompany(request);
                });

            Field<ListGraphType<CompanyGraphType>>(
                "companies",
                arguments: new QueryArguments(new List<QueryArgument>
                {
                    new QueryArgument<ListGraphType<IntGraphType>>
                    {
                        Name = "companyIds"
                    },
                    new QueryArgument<ListGraphType<StringGraphType>>
                    {
                        Name = "companyNames"
                    },
                     new QueryArgument<BooleanGraphType>
                    {
                        Name = "isActive"
                    },
                    new QueryArgument<IntGraphType>
                    {
                        Name = "page"
                    },
                    new QueryArgument<IntGraphType>
                    {
                        Name = "pageSize"
                    }
                }),
                resolve: delegate (ResolveFieldContext<object> context)
                {
                    var columns = context.GetMainSelectedFields();
                    var companyIds = context.GetArgument<int?[]>("companyIds");
                    var companyNames = context.GetArgument<string[]>("companyNames");
                    var isActive = context.GetArgument<bool?>("isActive");

                    var page = context.GetArgument<int?>("page");
                    var pageSize = context.GetArgument<int?>("pageSize");

                    var request = new SearchCompanies()
                    {
                        Ids = companyIds,
                        Names = companyNames,
                        IsActive = isActive,
                        Page = page,
                        PageSize = pageSize,
                        Columns = columns
                    };
                    return companyService.GetCompanies(request);
                });

            #endregion
        }
    }
}
```

{% endcode %}

## Build & Run & Test

### Create Database

Öncelikle yeni bir SQL SERVER veritabanı açmalısınız.

Sonrasında database klasörü içerisinde yer alan create-table.sql dosyasını çalıştırmalısınız.

{% code title="create-table.sql" %}

```sql
-- auto-generated definition
create table Company
(
    Id       int identity
        constraint Company_pk
            primary key nonclustered,
    Name     nvarchar(200) not null,
    IsActive bit default 1 not null
)
go

create unique index Company_Id_uindex
    on Company (Id)
go


```

{% endcode %}

Sizlerin projeyi test edebilmesi için; database klasörünün içerisinde yer alan bulk-data.sql dosyasını oluşturdum, bu dosyayı çalıştırabilirsiniz.&#x20;

Projenin AppSettings dosyasını kendi connectionString değerlerinize göre güncellemesiniz.

{% code title="appsettings.json" %}

```
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "SqlServerDatabaseConnection": "Server=localhost;Database=GraphQLSample;User Id=sa;Password=Aa123456;"
  }
}

```

{% endcode %}

### DotNet Restore & Build & Run

Aşağıdaki komutları çalıştırıp projeyi ayağa kaldırabilirsiniz.

```
dotnet restore
dotnet build
dotnet run
```

### UI PlayGround&#x20;

Tarayıcınızdan <https://localhost:5001/ui/playground> adresine gitmek istediğinizde; sorgularınızı test edebileceğiniz bir arayüze erişebilmeniz gerekmektedir.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LsJMcO3Q17Gb-t25imO%2F-LsJSx0RA55kGPCaKww8%2Fimage.png?alt=media\&token=c214bcbd-6494-4930-adb4-5434929cc066)

### Hello GraphQL For .Net

Aşağıdaki sorguyu yazdığınızda çıktısını almalısınız.

```
query {
  company(companyId:5) {
    id
    name
    isActive
  }
}
```

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LsJMcO3Q17Gb-t25imO%2F-LsJTbH_EAsAmJfOTf9x%2Fimage.png?alt=media\&token=4ca199c1-e4f9-490b-9f48-74949fe803d0)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://post.cagdaskarademir.com/post-2019/asp.net-core-api-ile-graphql-projesi-olusturmak.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
