Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

ASP.NET Core GraphQL API Development

ASP.NET Core ile GraphQL API oluşturmak, modern web uygulamaları için esnek ve verimli bir yol sunar. GraphQL, istemcinin belirli veri yapılarına yönelik isteklerde bulunabileceği bir sorgulama dilidir. Bu, istemcilerin yalnızca ihtiyaç duydukları verileri almasını sağlar, böylece ağ trafiği azalır ve performans artar.

Getting Started with GraphQL

What is GraphQL?

GraphQL, modern web uygulamalarında veri iletişimi için kullanılan bir sorgu dili ve çalışma zamanı ortamıdır. 2015 yılında Facebook tarafından geliştirilmeye başlanmıştır ve daha sonra 2018’de açık kaynaklı hale getirilmiştir. GraphQL, istemcilerin ihtiyaç duydukları verileri tek bir istekle sunucudan alabilmelerini sağlayan bir alternatif API sorgulama yöntemidir.

GraphQL’in temel özellikleri şunlardır:

  1. Esnek Veri Alma: GraphQL, istemcilerin ihtiyaç duyduğu verileri belirleyebilecekleri ve yalnızca istedikleri verileri alabilecekleri esnek bir yapı sunar. Bu sayede, aşırı veya eksik veri alımı gibi sorunlar minimize edilir.
  2. Tek Bir Endpoint: GraphQL, RESTful API’lerden farklı olarak tek bir endpoint sağlar. Bu, istemcilerin farklı veri parçalarını almak için farklı endpoint’lere ihtiyaç duymadan tüm verileri aynı endpoint üzerinden alabilmesini sağlar.
  3. Şemaya Dayalı Yaklaşım: GraphQL, bir şema (schema) kullanır. Şema, sunucu tarafında kullanılabilir olan veri türlerini ve bu veri türlerine ait alanları (fields) tanımlar. İstemciler, bu şema üzerinde tanımlı olan verilere erişirler.
  4. Kolaylaştırılmış Dökümantasyon: GraphQL, verilerin nasıl alınacağına dair otomatik olarak oluşturulan ve güncellenen bir dökümantasyon sağlar. Bu, geliştiricilerin API’yi daha iyi anlamalarına ve kullanmalarına yardımcı olur.

GraphQL, çeşitli programlama dilleri ve platformlar arasında geniş bir destek sağlar. ASP.NET Core ile birlikte, GraphQL sunucuları oluşturmak için popüler kütüphanelerden biri olan Hot Chocolate gibi çeşitli kütüphaneler bulunmaktadır.

Örnek bir GraphQL sorgusu:

query {
  user(id: 123) {
    id
    name
    email
    posts {
      title
      content
    }
  }
}

Yukarıdaki sorgu, belirli bir kullanıcının (ID’si 123 olan) adını, e-posta adresini ve sahip olduğu gönderilerin başlık ve içeriğini almak için kullanılabilir.

GraphQL, geliştiricilere esneklik ve verimlilik sağlayan modern bir API sorgulama yaklaşımıdır. Büyük ve karmaşık veri yapılarıyla çalışan uygulamalar için özellikle uygun olan GraphQL, web geliştirme dünyasında giderek daha popüler hale gelmektedir.

GraphQL vs. REST

GraphQL ve REST, modern web uygulamalarında veri iletişimi için kullanılan iki farklı API sorgulama yaklaşımıdır. Her ikisi de belirli avantajlara ve kullanım senaryolarına sahiptir. Bu iki yaklaşımı derinlemesine inceleyelim:

GraphQL

GraphQL, istemcilerin ihtiyaç duydukları verileri belirleyebilecekleri ve yalnızca istedikleri verileri alabilecekleri esnek bir yapı sunar. Bu nedenle, GraphQL’in bazı önemli avantajları şunlardır:

  1. Esnek Veri Alma: GraphQL, istemcilerin istedikleri verileri belirleyebilecekleri ve yalnızca bu verileri alabilecekleri bir yapı sunar. Bu, aşırı veya eksik veri alımını minimize eder.
  2. Tek Bir Endpoint: GraphQL, tek bir endpoint sağlar. Bu, istemcilerin farklı veri parçalarını almak için farklı endpoint’lere ihtiyaç duymadan tüm verileri aynı endpoint üzerinden alabilmesini sağlar.
  3. Şemaya Dayalı Yaklaşım: GraphQL, bir şema kullanır. Şema, sunucu tarafında kullanılabilir olan veri türlerini ve bu veri türlerine ait alanları tanımlar. İstemciler, bu şema üzerinde tanımlı olan verilere erişirler.
  4. Kolaylaştırılmış Dökümantasyon: GraphQL, otomatik olarak oluşturulan ve güncellenen bir dökümantasyon sağlar. Bu, geliştiricilerin API’yi daha iyi anlamalarına ve kullanmalarına yardımcı olur.
REST

REST, Representational State Transfer’ın kısaltmasıdır ve temelde kaynaklar üzerinde HTTP protokolü aracılığıyla işlem yapmayı sağlar. REST’in bazı önemli avantajları şunlardır:

  1. Basitlik ve Standartlar: REST, basitlik ilkesine dayanır ve HTTP protokolüyle uyumlu olduğu için standartlaştırılmıştır. Bu, RESTful API’lerin anlaşılması ve kullanılması kolaydır.
  2. Cachleme ve Önbellekleme: REST, HTTP’in cache özelliğini kullanarak önbellekleme ve performans iyileştirmeleri sağlar.
  3. Stateless (Durumsuz) Mimari: RESTful servisler durumsuzdur, yani her istek kendi içinde bağımsızdır ve sunucu tarafında saklanan herhangi bir durum (state) bulunmaz. Bu, ölçeklenebilirliği artırır.
  4. Geniş Destek: REST, uzun bir geçmişe ve geniş bir destek tabanına sahiptir. Birçok platform ve programlama dili RESTful servisler oluşturmayı destekler.
Karşılaştırma

GraphQL ve REST arasındaki seçim, projenin gereksinimlerine ve kullanım senaryolarına bağlıdır. İşte bazı karşılaştırma noktaları:

  1. Veri Alma Esnekliği: GraphQL, istemcilere daha fazla esneklik sağlar ve istedikleri verileri belirleyebilmelerine olanak tanır. REST ise, genellikle önceden tanımlanmış kaynakları ve bu kaynaklara ait belirli veri yapılarını sunar.
  2. Performans: REST, önbellekleme ve cachleme gibi HTTP’nin doğal özelliklerinden yararlanarak performansı artırabilir. GraphQL ise, gereksinimlere göre belirli bir veri yapısını getirmek için optimize edilebilir.
  3. Dökümantasyon ve Anlaşılabilirlik: GraphQL otomatik olarak dökümantasyon sağlar ve API’nin anlaşılmasını kolaylaştırır. REST, iyi tasarlanmış dökümantasyon ile birlikte kullanıldığında anlaşılabilir olabilir, ancak bu dökümantasyonu oluşturmak geliştiricilere düşer.

Her iki yaklaşımın da kendine özgü avantajları ve kullanım senaryoları vardır. Projeye ve gereksinimlere bağlı olarak, GraphQL veya REST’ten biri daha uygun olabilir.

Open-source GraphQL projects

GraphQL’i ASP.NET Core projelerinizde kullanmak için bir dizi açık kaynaklı GraphQL kütüphanesi bulunmaktadır. Bu kütüphaneler, GraphQL sorgularını işlemek, GraphQL sunucuları oluşturmak ve ASP.NET Core ile GraphQL API’lerini entegre etmek için kullanılabilir.

  1. Hot Chocolate: Hot Chocolate, .NET geliştiricilerine yönelik bir GraphQL uygulama sunucusu kütüphanesidir. ASP.NET Core projelerinde GraphQL API’leri oluşturmak için kullanılabilir. Hot Chocolate, performans odaklıdır ve tüm GraphQL özelliklerini destekler.
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGraphQLServer()
                .AddQueryType<Query>()
                .AddMutationType<Mutation>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGraphQL();
        });
    }
}

GraphQL.NET: GraphQL.NET, .NET platformunda GraphQL sunucuları oluşturmak için kullanılan bir kütüphanedir. ASP.NET Core ile entegrasyonu kolaydır ve geniş bir topluluğa sahiptir. GraphQL.NET, GraphQL şemalarını ve sorgularını işlemek için kapsamlı bir yapı sunar.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddGraphQLServer()
                .AddQueryType<Query>()
                .AddMutationType<Mutation>()
                .AddSubscriptionType<Subscription>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGraphQL();
            endpoints.MapControllers();
        });
    }
}

GraphQL.Client: GraphQL sorgularını göndermek ve GraphQL API’lerine erişmek için kullanılan bir istemci kütüphanesidir. .NET projelerinde GraphQL API’leriyle etkileşime geçmek için kullanılabilir.

var graphQLClient = new GraphQLHttpClient("https://api.example.com/graphql", new NewtonsoftJsonSerializer());
var request = new GraphQLRequest
{
    Query = @"
        query {
            posts {
                id
                title
            }
        }
    "
};

var response = await graphQLClient.SendQueryAsync<PostsResponse>(request);

Bu kütüphaneler, ASP.NET Core projelerinizde GraphQL API’leri oluşturmanıza, GraphQL sorgularını işlemenize ve GraphQL istemcileriyle etkileşime geçmenize olanak tanır. Her birinin kendine özgü avantajları ve kullanım durumları vardır. Projeye ve gereksinimlere bağlı olarak en uygun olanı seçebilirsiniz.

.NET Web API project overview

.NET Web API projeleri, HTTP protokolü üzerinden HTTP isteklerini alıp işleyen ve HTTP yanıtları üreten uygulamalardır. ASP.NET Core ile .NET Web API projeleri oluşturmak oldukça yaygındır. Bu projeler genellikle veri sunumu veya dış sistemlerle iletişim için kullanılır ve genellikle JSON veya XML gibi formatlarda veri alışverişi yaparlar.

Proje Oluşturma

Visual Studio veya .NET CLI gibi araçlar kullanılarak yeni bir .NET Web API projesi oluşturulabilir. Örnek olarak, .NET CLI kullanarak bir Web API projesi oluşturmak için aşağıdaki komutu kullanabilirsiniz:

dotnet new webapi -n MyWebApiProject

Bu komut, “MyWebApiProject” adında yeni bir .NET Web API projesi oluşturur.

Temel Yapı

.NET Web API projeleri, birkaç temel bileşenden oluşur:

  1. Controllers (Kontroller): Kontroller, gelen HTTP isteklerini alıp işleyen ve HTTP yanıtlarını üreten sınıflardır. Genellikle bu sınıflar, [ApiController] niteliğiyle işaretlenirler ve HTTP isteklerini yönlendirecek metotları içerirler.
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }

    [HttpGet]
    public async Task<IActionResult> GetProducts()
    {
        var products = await _productService.GetProductsAsync();
        return Ok(products);
    }

    // Diğer HTTP metotları buraya eklenebilir
}

Dependency Injection (Bağımlılık Enjeksiyonu): .NET Core ve ASP.NET Core, dependency injection (bağımlılık enjeksiyonu) için yerleşik destek sağlar. Bu, bağımlılıkların (servislerin) bir bileşenden diğerine enjekte edilmesini sağlar ve uygulamanın test edilebilirliğini ve esnekliğini artırır.

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IProductService, ProductService>();
    // Diğer servisler buraya eklenebilir
}

Routing (Yönlendirme): Routing, gelen HTTP isteklerini ilgili kontrollere yönlendiren mekanizmayı sağlar. Routing, Startup sınıfındaki Configure yönteminde yapılandırılır.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}
  1. Middleware (Ara Yazılım): Middleware, HTTP istekleri ve yanıtları işlemek için kullanılan bileşenlerdir. Örneğin, kimlik doğrulama, loglama, önbellekleme gibi işlevler middleware’ler aracılığıyla gerçekleştirilebilir.
Sonuç

.NET Web API projeleri, HTTP protokolü üzerinden veri alışverişi sağlayan ve genellikle JSON veya XML formatında veri sunan uygulamalardır. Bu projeler, ASP.NET Core altında geliştirilir ve genellikle RESTful API’lerin oluşturulması için kullanılırlar. Proje oluşturma, kontrolörler, bağımlılık enjeksiyonu, yönlendirme ve ara yazılım gibi temel bileşenlerden oluşurlar ve genellikle Visual Studio veya .NET CLI gibi araçlar kullanılarak oluşturulurlar.

Setting up GraphQL in Web API

GraphQL’i ASP.NET Core Web API projenize entegre etmek oldukça kolaydır. GraphQL’i kullanmak için öncelikle bir GraphQL sunucusu oluşturmanız gerekir. Bu, gelen GraphQL sorgularını işleyecek ve uygun yanıtları döndürecek bir yapıdır. Hot Chocolate veya GraphQL.NET gibi popüler GraphQL kütüphanelerinden birini kullanarak bu işlemi gerçekleştirebilirsiniz.

  1. Hot Chocolate Kütüphanesini Projeye Ekleme: İlk adım olarak, projenize Hot Chocolate kütüphanesini eklemeniz gerekir. Bu işlemi NuGet Paket Yöneticisi’ni veya .NET CLI aracılığıyla yapabilirsiniz.
dotnet add package HotChocolate.AspNetCore

GraphQL Sunucusunu Oluşturma: Startup.cs dosyasındaki ConfigureServices metodu içinde, bir GraphQL sunucusu ekleyin.

using HotChocolate;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        
        // Hot Chocolate ekleniyor
        services.AddGraphQLServer()
                .AddQueryType<Query>(); // Query tipi burada belirtilmeli
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // Middleware'leri ekleme
        app.UseRouting();
        app.UseAuthorization();
        
        // GraphQL endpoint'ini etkinleştirme
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGraphQL();
            endpoints.MapControllers();
        });
    }
}

Query Tipini Tanımlama: GraphQL sorgularını işleyecek olan Query tipini tanımlayın.

using HotChocolate.Types;

public class Query
{
    [UseDbContext(typeof(AppDbContext))] // Veritabanı bağlamı burada belirtilmeli
    public IQueryable<Product> GetProducts([ScopedService] AppDbContext context)
    {
        return context.Products;
    }
}

Veritabanı Bağlamını Ekleme: GraphQL sorgularını işlerken veritabanıyla etkileşime geçmek istiyorsanız, bu adımda veritabanı bağlamınızı ekleyin.

public class AppDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }

    // Diğer DbSet'ler buraya eklenebilir

    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }
}

Controller Ekleme (Opsiyonel): İstemcilerin GraphQL sorgularını gönderebilecekleri bir Controller ekleyebilirsiniz.

using Microsoft.AspNetCore.Mvc;

[Route("graphql")]
[ApiController]
public class GraphQLController : ControllerBase
{
    private readonly IRequestExecutor _executor;

    public GraphQLController(IRequestExecutor executor)
    {
        _executor = executor;
    }

    [HttpPost]
    public async Task<IActionResult> PostAsync([FromBody] GraphQLRequest request)
    {
        IExecutionResult result = await _executor.ExecuteAsync(request.Query);
        return Ok(result);
    }
}

Bu adımları takip ederek, ASP.NET Core Web API projenize GraphQL desteği ekleyebilirsiniz. Bu sayede istemciler, GraphQL sorgularını gönderebilir ve gerekli verilere erişebilirler. Unutmayın ki, Hot Chocolate veya GraphQL.NET gibi kütüphaneleri kullanarak GraphQL sunucunuzu özelleştirebilir ve projenize uygun hale getirebilirsiniz.

Data Querying with GraphQL in .NET Web API

Operations in GraphQL

GraphQL’de operasyonlar (operations), istemcilerin sunucudan veri almak için kullandıkları sorgulama veya değişiklik işlemleridir. GraphQL, iki temel operasyon türünü destekler: sorgular (queries) ve mutasyonlar (mutations). Her iki operasyon türü de belirli bir amaç için kullanılır.

1. Sorgular (Queries)

Sorgular, GraphQL istemcilerinin sunucudan veri almak için kullandığı operasyonlardır. Sorgular, mevcut veriye salt okunur erişim sağlar, yani veritabanındaki verileri sorgulamak ve döndürmek için kullanılır. Sorgular, veritabanından veri almak, bir API’den veri çekmek veya hesaplamalar yapmak gibi işlemler için kullanılabilir.

Örnek bir GraphQL sorgusu:

query {
  books {
    title
    author
  }
}

Yukarıdaki sorgu, “books” alanından kitapların başlıklarını ve yazarlarını almak için kullanılır.

2. Mutasyonlar (Mutations)

Mutasyonlar, GraphQL istemcilerinin sunucuda veri değiştirmek veya ekleme yapmak için kullandığı operasyonlardır. Bu operasyonlar, veritabanındaki verileri güncellemek, yeni veri eklemek veya mevcut veriyi silmek için kullanılabilir.

Örnek bir GraphQL mutasyonu:

mutation {
  addBook(title: "GraphQL for Beginners", author: "John Doe") {
    id
    title
    author
  }
}

Yukarıdaki mutasyon, yeni bir kitap eklemek için kullanılır. Sunucu, “GraphQL for Beginners” adlı bir kitap ekler ve eklenen kitabın bilgilerini yanıt olarak döndürür.

Örnek Kodlar

ASP.NET Core Web API projesinde sorguları ve mutasyonları nasıl tanımlayacağınızı gösteren örnek kodlar:

  1. Sorgular (Queries)
public class Query
{
    [UseDbContext(typeof(AppDbContext))] 
    public IQueryable<Book> GetBooks([ScopedService] AppDbContext context)
    {
        return context.Books;
    }

    [UseDbContext(typeof(AppDbContext))] 
    public async Task<Book> GetBookById([ScopedService] AppDbContext context, int id)
    {
        return await context.Books.FindAsync(id);
    }
}

Mutasyonlar (Mutations)

public class Mutation
{
    [UseDbContext(typeof(AppDbContext))] 
    public async Task<Book> AddBook([ScopedService] AppDbContext context, string title, string author)
    {
        var newBook = new Book { Title = title, Author = author };
        context.Books.Add(newBook);
        await context.SaveChangesAsync();
        return newBook;
    }

    [UseDbContext(typeof(AppDbContext))] 
    public async Task<Book> UpdateBookTitle([ScopedService] AppDbContext context, int id, string newTitle)
    {
        var book = await context.Books.FindAsync(id);
        if (book != null)
        {
            book.Title = newTitle;
            await context.SaveChangesAsync();
        }
        return book;
    }

    [UseDbContext(typeof(AppDbContext))] 
    public async Task<bool> DeleteBook([ScopedService] AppDbContext context, int id)
    {
        var book = await context.Books.FindAsync(id);
        if (book != null)
        {
            context.Books.Remove(book);
            await context.SaveChangesAsync();
            return true;
        }
        return false;
    }
}

Yukarıdaki örneklerde, Query ve Mutation sınıfları, sorguları ve mutasyonları tanımlar. Her bir metot, belirli bir operasyonu gerçekleştirir ve gerekli veritabanı işlemlerini yapar. Bu yöntemler, veri sorgulamak veya değişiklik yapmak için kullanılabilir ve GraphQL API’si tarafından çağrılabilirler.

Types in GraphQL

GraphQL’de “types” (tipler), veri modelini ve sunucu tarafında kullanılabilir veri yapılarını temsil eder. Her GraphQL sorgusu veya mutasyonu bir veya daha fazla tip kullanır. Bu tipler, sunucu tarafında tanımlanır ve GraphQL şeması içinde belirtilir. Types, belirli bir veri parçasını temsil eder ve bu verinin hangi alanlardan oluştuğunu tanımlar.

1. Scalar Types (Skaler Tipler)

Skaler tipler, tek bir değeri temsil eden basit tiplerdir. GraphQL’in yerleşik skaler tipleri şunlardır:

  • String: Metin verilerini temsil eder.
  • Int: Tamsayı değerlerini temsil eder.
  • Float: Ondalık sayıları temsil eder.
  • Boolean: Doğru veya yanlış değerlerini temsil eder.
  • ID: Benzersiz tanımlayıcıları temsil eder.

Örnek bir skaler tip tanımı:

type Product {
  id: ID!
  name: String!
  price: Float!
  inStock: Boolean!
}
2. Object Types (Nesne Tipleri)

Nesne tipleri, GraphQL’de karmaşık veri yapılarını temsil eder. Bunlar, bir veya daha fazla alanı içeren ve diğer tiplerle ilişkili olabilen tiplerdir. Örneğin, bir kitap nesnesi bir başlık, bir yazar ve bir yayın tarihi içerebilir.

Örnek bir nesne tip tanımı:

type Book {
  title: String!
  author: String!
  publishedDate: String!
}
3. List Types (Liste Tipleri)

Liste tipleri, bir veya daha fazla öğenin listesini temsil eder. Örneğin, bir kitapçıdaki tüm kitapları listeleyen bir sorgu sonucu bir liste tipi olabilir.

Örnek bir liste tip tanımı:

type Query {
  books: [Book!]!
}
4. Input Types (Giriş Tipleri)

Giriş tipleri, mutasyonlar için kullanılan parametreleri tanımlar. Bu tipler, bir sorgu isteğinde kullanılan alanların aksine, verileri sunucuya göndermek için kullanılır.

Örnek bir giriş tip tanımı:

input NewProductInput {
  name: String!
  price: Float!
}
5. Enum Types (Enum Tipleri)

Enum tipleri, belirli bir sınırlı değer kümesini temsil eder. Örneğin, bir kitabın durumu “Yayınlandı”, “Baskıda” veya “Stokta Değil” gibi belirli değerlerden biri olabilir.

Örnek bir enum tip tanımı:

enum BookStatus {
  PUBLISHED
  IN_PRINT
  OUT_OF_STOCK
}
Örnek Kodlar

ASP.NET Core Web API projenizde GraphQL şeması içinde tipleri nasıl tanımlayacağınızı gösteren örnek bir kod:

public class BookType : ObjectType<Book>
{
    protected override void Configure(IObjectTypeDescriptor<Book> descriptor)
    {
        descriptor.Field(b => b.Title).Type<NonNullType<StringType>>();
        descriptor.Field(b => b.Author).Type<NonNullType<StringType>>();
        descriptor.Field(b => b.PublishedDate).Type<NonNullType<StringType>>();
    }
}

public class QueryType : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor.Field(q => q.GetBooks()).Type<NonNullType<ListType<NonNullType<BookType>>>>();
    }
}

public class MutationType : ObjectType<Mutation>
{
    protected override void Configure(IObjectTypeDescriptor<Mutation> descriptor)
    {
        descriptor.Field(m => m.AddBook(default)).Type<NonNullType<BookType>>().Argument("input", a => a.Type<NonNullType<NewBookInputType>>());
    }
}

public class NewBookInputType : InputObjectType<NewBookInput>
{
    protected override void Configure(IInputObjectTypeDescriptor<NewBookInput> descriptor)
    {
        descriptor.Field(i => i.Title).Type<NonNullType<StringType>>();
        descriptor.Field(i => i.Author).Type<NonNullType<StringType>>();
        descriptor.Field(i => i.PublishedDate).Type<NonNullType<StringType>>();
    }
}

Yukarıdaki örnekte, BookType, QueryType, MutationType ve NewBookInputType adında GraphQL tipleri tanımlanmıştır. Bu tipler, GraphQL şeması içinde kullanılacak ve istemcilere sunucudan veri almak veya veri değiştirmek için kullanılacaktır.

Adding your first object graph type (course entity)

GraphQL’de nesne grafik tipleri (object graph types), bir veri modelinin veya varlık (entity) türlerinin GraphQL’deki temsilidir. .NET Web API projenizde GraphQL kullanarak ilk nesne grafik tipini (course entity) eklemek için aşağıdaki adımları izleyebilirsiniz:

  1. Course Entity Tanımlama: İlk adım olarak, projenizde temsil edilecek olan ders varlığını (course entity) tanımlayın. Bu, veritabanınızda veya uygulamanızda saklanan ders bilgilerini temsil eden bir sınıf olacaktır.
public class Course
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public int Credits { get; set; }
}

GraphQL Tipini Tanımlama: Daha sonra, GraphQL’de bu ders varlığını temsil edecek bir GraphQL nesne grafik tipi (object graph type) tanımlayın.

using HotChocolate.Types;

public class CourseType : ObjectType<Course>
{
    protected override void Configure(IObjectTypeDescriptor<Course> descriptor)
    {
        descriptor.Field(c => c.Id).Type<NonNullType<IdType>>();
        descriptor.Field(c => c.Title).Type<NonNullType<StringType>>();
        descriptor.Field(c => c.Description).Type<NonNullType<StringType>>();
        descriptor.Field(c => c.Credits).Type<NonNullType<IntType>>();
    }
}

Query Tipini Güncelleme: Eğer dersleri sorgulamak için bir yöntem (method) eklediyseniz, bu yöntemi GraphQL sorguları aracılığıyla erişilebilir hale getirin ve dersleri döndüren bir alan tanımlayın.

using HotChocolate;
using HotChocolate.Types;
using System.Collections.Generic;
using System.Linq;

public class Query
{
    private readonly List<Course> _courses = new List<Course>
    {
        new Course { Id = 1, Title = "Mathematics", Description = "Introduction to Mathematics", Credits = 3 },
        new Course { Id = 2, Title = "History", Description = "World History", Credits = 4 },
        new Course { Id = 3, Title = "Computer Science", Description = "Introduction to Computer Science", Credits = 3 }
    };

    [UseDbContext(typeof(AppDbContext))] 
    public IQueryable<Course> GetCourses()
    {
        return _courses.AsQueryable();
    }
}

Schema Güncelleme: Son olarak, GraphQL şemanızı güncelleyin ve yeni ders nesne grafik tipini ekleyin.

using HotChocolate;

public class QueryType : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor.Field(q => q.GetCourses()).Type<NonNullType<ListType<NonNullType<CourseType>>>>();
    }
}

Yukarıdaki adımları takip ederek, ASP.NET Core Web API projenize GraphQL’i entegre edebilir ve ilk nesne grafik tipinizi (course entity) tanımlayabilirsiniz. Bu şekilde, istemciler ders verilerine GraphQL sorguları aracılığıyla erişebilirler.

Adding your first query: All courses


GraphQL’de bir sorgu (query) tanımlamak, istemcilere sunucudan belirli veri parçalarını getirmek için kullanılır.

  1. Query Metodunu Tanımlama: İlk adım olarak, tüm kursları getiren bir sorgu metodu tanımlayın. Bu metot, sunucudaki mevcut tüm kursları döndürecektir.
using HotChocolate;
using System.Collections.Generic;
using System.Linq;

public class Query
{
    private readonly List<Course> _courses = new List<Course>
    {
        new Course { Id = 1, Title = "Mathematics", Description = "Introduction to Mathematics", Credits = 3 },
        new Course { Id = 2, Title = "History", Description = "World History", Credits = 4 },
        new Course { Id = 3, Title = "Computer Science", Description = "Introduction to Computer Science", Credits = 3 }
    };

    [UseDbContext(typeof(AppDbContext))] 
    public IQueryable<Course> GetCourses()
    {
        return _courses.AsQueryable();
    }
}

Yukarıdaki kodda, Query sınıfına GetCourses adında bir metot ekledik. Bu metot, _courses listesini IQueryable’e dönüştürerek döndürür. Gerçek bir veritabanı kullanıyorsanız, bu metot veritabanından tüm kursları sorgulamak için uygun bir yönteme erişebilir.

  1. Query Tipini Tanımlama: Daha sonra, GraphQL şemanızı güncelleyerek bu sorguyu belirten bir alan (field) tanımlayın. Bu, istemcilerin sunucudan tüm kursları almak için kullanacakları bir alan olacaktır.
using HotChocolate.Types;

public class QueryType : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor.Field(q => q.GetCourses()).Type<NonNullType<ListType<NonNullType<CourseType>>>>();
    }
}

Yukarıdaki kodda, QueryType sınıfına GetCourses metodu için bir alan (field) tanımladık. Bu alan, GraphQL istemcilerine tüm kursları almak için kullanılabilir ve CourseType tarafından tanımlanan bir nesne tipi listesini döndürür.

  1. Schema Güncelleme: Son olarak, GraphQL şemanızı güncelleyin ve yeni sorguyu ekleyin.
using HotChocolate;

public class Schema : GraphQL.Types.Schema
{
    public Schema(QueryType query, MutationType mutation)
        : base(query, mutation)
    {
    }
}

Yukarıdaki adımları tamamladıktan sonra, ASP.NET Core Web API projenize GraphQL entegrasyonunu tamamlayabilir ve istemcilere sunucudan tüm kursları almak için kullanabilecekleri bir sorgu eklemiş olursunuz. Bu sayede, istemciler GraphQL sorguları kullanarak sunucudan veri alabilirler.

Adding your GraphQL schema file

GraphQL şema dosyası, GraphQL API’sinin yapısal tanımını içeren bir dosyadır. Bu dosya, sunucunun desteklediği sorgu ve mutasyonları, veri tiplerini ve bu tiplerin alanlarını tanımlar. ASP.NET Core Web API projesinde GraphQL kullanırken, bir GraphQL şema dosyası eklemek, sorguları ve mutasyonları tanımlamanın yanı sıra, API’nin kullanıcılarına sunacağı veri tiplerini belirlemek için kullanışlıdır.

  1. GraphQL Şema Dosyası Oluşturma: İlk olarak, projenizin kök dizinine bir GraphQL şema dosyası oluşturun. Bu dosyanın adı genellikle schema.graphql veya schema.schema gibi olur. Bu dosya, GraphQL sorgularını ve mutasyonlarını tanımlayacak ve sunucunun desteklediği veri tiplerini belirleyecektir.
type Query {
  hello: String
}

Yukarıdaki örnek, basit bir GraphQL şemasıdır. Query tipi, sunucunun kullanıcılara sunacağı sorguları tanımlar. Bu örnekte, hello adında bir alan (field) tanımlanmıştır ve bu alan bir metin dizesi (String) döndürür.

  1. Şema Dosyasını Yükleme: Şema dosyasını projenize ekleyin. Bu dosyayı projenin kök dizinine veya isteğe bağlı bir klasöre yerleştirebilirsiniz.
  2. Şemanın Yüklenmesi ve Kullanılması: Şema dosyasını projeye yükledikten sonra, projenin başlangıç noktasında bu şemanın yüklendiğinden emin olun. Ardından, GraphQL sunucunuzun bu şemayı kullanmasını sağlayacak bir yapılandırma adımı ekleyin.
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // GraphQL servisini ekleme ve şema dosyasını yükleme
        services.AddGraphQLServer()
                .AddDocumentFromFile("path/to/schema.graphql"); // Şema dosyasının yolunu belirtin
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // Middleware'leri ekleme
        app.UseRouting();
        app.UseAuthorization();

        // GraphQL endpoint'ini etkinleştirme ve şemanın yüklenmesi
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGraphQL();
        });
    }
}

Yukarıdaki örnekte, AddDocumentFromFile() yöntemi çağrısıyla, projenizin kök dizinindeki schema.graphql dosyasını yükledik. Bu, GraphQL sunucunuzun projenizin şemasını tanımasını sağlar ve istemcilere sunucudan veri almak veya değiştirmek için kullanabilecekleri sorguları ve mutasyonları belirler.

Bu adımları takip ederek, ASP.NET Core Web API projenize bir GraphQL şema dosyası ekleyebilir ve projenizdeki GraphQL sorgularını, mutasyonları ve veri tiplerini tanımlayabilirsiniz. Bu sayede, istemciler GraphQL sorguları kullanarak sunucudan veri alabilir ve değiştirebilirler.

Testing

GraphQL API’lerini test etmek, sunucu tarafındaki mantığı doğrulamak ve API’nin beklenen davranışları sergilemesini sağlamak için önemlidir. ASP.NET Core Web API’de GraphQL sorgularını ve mutasyonlarını test etmek için birkaç farklı yöntem vardır.

  1. Integration Testing: Tüm GraphQL API’yi test etmek için Integration Test adı verilen bir yaklaşım kullanılabilir. Bu testler, API’nin gerçek HTTP isteklerini kabul edip cevap verdiği gibi davranışlarını kontrol eder. Bu, API’nin tam olarak nasıl davrandığını doğrulamak için oldukça etkili bir yöntemdir.
  2. Unit Testing: GraphQL API’de sorguları ve mutasyonları tek tek test etmek için Unit Testler kullanılabilir. Bu testler, belirli bir sorgunun veya mutasyonun beklenen sonuçları üretip üretmediğini kontrol eder. Bu yöntem, API’nin her parçasını ayrı ayrı test etmek ve hataları hızlıca belirlemek için uygundur.
  3. Mocking Dependencies: API, harici kaynaklara (veritabanları, servisler, vb.) bağımlılıklarını azaltmak için Dependency Injection kullanabilir. Bu durumda, bu bağımlılıkları mocklayarak API davranışını izole bir şekilde test edebilirsiniz.

İşte bu yöntemlerin uygulanması için genel bir adım adım yaklaşım:

Integration Testing:
  1. Test Ortamını Ayarlama: Testleriniz için ayrı bir ortam oluşturun ve API’yi bu ortamda başlatın. Bu, gerçek HTTP istekleri göndererek API’nin çalışmasını test etmenizi sağlar.
  2. HTTP İstekleri Gönderme: Oluşturduğunuz ortamda, gerçek HTTP isteklerini oluşturun ve API’ye gönderin. Bu istekler aracılığıyla sorguları ve mutasyonları test edin.
  3. Cevapları Kontrol Etme: API’den gelen cevapları kontrol edin ve beklenen sonuçları doğrulayın. Başarılı ve başarısız senaryoları test edin.
Unit Testing:
  1. Test Ortamını Ayarlama: Unit testleriniz için gerekli test ortamını oluşturun. Bu, API’nin bağımlılıklarını (veritabanları, servisler, vb.) mocklayarak API’nin davranışını izole bir şekilde test etmenizi sağlar.
  2. GraphQL Sorgularını ve Mutasyonlarını Çağırma: API’nin belirli sorgularını veya mutasyonlarını çağırın ve API’nin dönüş değerlerini kontrol edin.
  3. Mocklanmış Bağımlılıkları Kontrol Etme: API’nin bağımlılıklarını mocklayarak, bu bağımlılıklardan beklenen davranışları test edin. Mocklanmış bağımlılıklar, gerçek sistemlerin yerine geçer ve testlerin daha hızlı ve güvenilir bir şekilde çalışmasını sağlar.
Mocking Dependencies:
  1. Bağımlılıkları Mocklama: API’nin bağımlılıklarını (veritabanları, servisler, vb.) mocklayarak, API’nin davranışını izole bir şekilde test etme imkanı elde edin. Bu, API’nin belirli bir bağımlılığa nasıl tepki verdiğini test etmenizi sağlar.
  2. Bağımlılıkları Kontrol Etme: Mocklanmış bağımlılıklar aracılığıyla, API’nin belirli bir bağımlılığa beklenen şekilde tepki verip vermediğini kontrol edin. Bu, API’nin bağımlılıklarla etkileşimini doğrulamanıza ve hataları tespit etmenize olanak tanır.

Örnek bir integration test (xUnit ve TestServer ile):

public class GraphQLTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    public GraphQLTests(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task GetCourses_ReturnsSuccessStatusCode()
    {
        var client = _factory.CreateClient();

        var response = await client.GetAsync("/graphql?query={ getCourses { id title description credits } }");

        response.EnsureSuccessStatusCode();
    }
}

Bu test, /graphql endpoint’ine bir GET isteği göndererek tüm kursları almayı dener. Sonuç başarı kodu döndüğünde, test başarılıdır.

Data Mutation with GraphQL in .NET Web API

What is a mutation?

Mutasyonlar (mutations), GraphQL’de veri değişikliklerini (ekleme, güncelleme, silme) gerçekleştirmek için kullanılan bir tür sorgu işlemidir. Mutasyonlar, GraphQL API’si tarafından sağlanan işlevler aracılığıyla belirli bir eylemi gerçekleştirmek için kullanıcılar tarafından gönderilen isteklerdir. Bu işlevler genellikle sunucu tarafında tanımlanan ve veritabanı işlemlerini gerçekleştiren metodlardır.

Bir mutasyon, bir GraphQL istemcisi tarafından gönderilen ve sunucunun veri üzerinde değişiklik yapmasını istediği bir istektir. Mutasyonlar, tipik olarak “create”, “update” ve “delete” gibi eylemleri gerçekleştirmek için kullanılır. Mutasyonlar, sorgu ile benzer bir şekilde gönderilir ancak işleme yeteneklerini belirtmek için mutation anahtar kelimesi kullanılır.

mutation {
  createPost(input: { title: "New Post", content: "This is a new post." }) {
    id
    title
    content
  }
}

Yukarıdaki örnekte, createPost adında bir mutasyon çağrılmaktadır. Bu mutasyon, title ve content alanlarını parametre olarak alır ve yeni bir gönderi (post) oluşturur. Mutasyonun sonucunda, oluşturulan gönderinin id, title ve content alanları döndürülür.

Mutasyonlar, GraphQL API’si tarafından sağlanan belirli bir işlevi çağırmak için kullanılır ve API’nin belirli bir veri kaynağını güncellemesini sağlar. Örneğin, bir blog uygulamasında, bir kullanıcının yeni bir gönderi oluşturmasını, mevcut bir gönderiyi güncellemesini veya bir gönderiyi silmesini sağlamak için mutasyonlar kullanılabilir.

İşte bir ASP.NET Core Web API projesinde bir mutasyonun örnek bir uygulaması:

public class Mutation
{
    private readonly BlogRepository _repository;

    public Mutation(BlogRepository repository)
    {
        _repository = repository;
    }

    public async Task<Post> CreatePost(CreatePostInput input)
    {
        // Yeni bir gönderi oluştur
        var post = new Post
        {
            Title = input.Title,
            Content = input.Content,
            CreatedAt = DateTime.UtcNow
        };

        // Veritabanına kaydet
        await _repository.AddPost(post);

        return post;
    }
}

Yukarıdaki örnekte, CreatePost adında bir mutasyon metodu tanımlanmıştır. Bu metot, CreatePostInput adında bir parametre alır ve bu parametrelerle yeni bir gönderi oluşturur. Daha sonra, oluşturulan gönderiyi veritabanına kaydeder ve oluşturulan gönderiyi döndürür.

Bu şekilde, ASP.NET Core Web API projenizde mutasyonları tanımlayabilir ve istemcilerin veriyi değiştirmesini sağlayabilirsiniz. Bu, API’nin dinamik ve değişken veri manipülasyonlarına olanak tanır.

Adding your first mutation: Add data


“Adding your first mutation: Add data” başlığı altında, ASP.NET Core Web API projenizde GraphQL kullanarak ilk mutasyonu (veri ekleme) tanımlamak için aşağıdaki adımları izleyebilirsiniz:

  1. Mutasyon Metodunu Tanımlama: İlk adım olarak, eklenecek veriye uygun bir mutasyon metodu tanımlayın. Örneğin, bir blog uygulamasında yeni bir gönderi eklemek için bir mutasyon tanımlayabilirsiniz.
public class Mutation
{
    private readonly BlogRepository _repository;

    public Mutation(BlogRepository repository)
    {
        _repository = repository;
    }

    public async Task<Post> AddPost(AddPostInput input)
    {
        // Yeni bir gönderi oluştur
        var post = new Post
        {
            Title = input.Title,
            Content = input.Content,
            CreatedAt = DateTime.UtcNow
        };

        // Veritabanına kaydet
        await _repository.AddPost(post);

        return post;
    }
}

Yukarıdaki örnekte, AddPost adında bir mutasyon metodu tanımlanmıştır. Bu metot, AddPostInput adında bir parametre alır ve bu parametrelerle yeni bir gönderi oluşturur. Daha sonra, oluşturulan gönderiyi veritabanına kaydeder ve oluşturulan gönderiyi döndürür.

  1. Giriş Tipini Tanımlama: Mutasyonun parametrelerini tanımlamak için bir giriş tipi (input type) tanımlayın.
public class AddPostInput
{
    public string Title { get; set; }
    public string Content { get; set; }
}

Yukarıdaki örnekte, AddPostInput adında bir giriş tipi tanımlanmıştır. Bu, AddPost mutasyonunun parametrelerini belirtir.

  1. GraphQL Şemasını Güncelleme: Mutasyonu GraphQL şemanıza ekleyin, böylece istemciler tarafından kullanılabilir hale gelir.
public class MutationType : ObjectType<Mutation>
{
    protected override void Configure(IObjectTypeDescriptor<Mutation> descriptor)
    {
        descriptor.Field(m => m.AddPost(default))
                  .Argument("input", a => a.Type<NonNullType<AddPostInputType>>())
                  .Type<NonNullType<PostType>>(); // Eklenen gönderiyi döndür
    }
}

Yukarıdaki kodda, AddPost mutasyonunu MutationType sınıfına ekledik. AddPost mutasyonunun bir giriş parametresi (input) alacağını ve bir PostType nesnesi döndüreceğini belirttik.

Bu adımları takip ettikten sonra, ASP.NET Core Web API projenizde GraphQL kullanarak bir mutasyonu (veri ekleme) tanımlamış olursunuz. Artık istemciler, API’nize GraphQL sorguları aracılığıyla yeni veri ekleyebilirler.

Add data: Testing

“Add data: Testing” başlığı altında, ASP.NET Core Web API projenizde GraphQL mutasyonlarını test etmek için birkaç farklı yöntem bulunmaktadır. Bu yöntemler arasında Integration Testing ve Unit Testing en yaygın olanlarıdır. İşte her iki yöntemin derinlemesine açıklamaları ve örnekleri:

1. Integration Testing:

Integration Testing, API’nizin tüm çalışma ortamını test etmek için kullanılır. Gerçek HTTP istekleri gönderilir ve API’nin davranışı gerçek bir ortamda doğrulanır. Bu, API’nin tüm katmanlarının (routing, controller, GraphQL sorgu işleme vb.) doğru çalıştığından emin olmanıza olanak tanır.

Adımlar:
  1. Test Ortamını Ayarlama: Testleriniz için bir test sunucusu oluşturun ve API’nizi bu sunucuda başlatın.
  2. GraphQL Mutasyonunu Çağırma: Oluşturulan test sunucusuna gerçek HTTP istekleri göndererek GraphQL mutasyonunu çağırın.
  3. Cevapları Kontrol Etme: API’nin geri döndürdüğü cevapları kontrol edin ve beklenen sonuçları doğrulayın.
Örnek Kod:
public class GraphQLIntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    public GraphQLIntegrationTests(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task AddPost_ReturnsCreatedPost()
    {
        var client = _factory.CreateClient();

        var mutation = @"
            mutation {
                addPost(input: { title: ""New Post"", content: ""This is a new post."" }) {
                    id
                    title
                    content
                }
            }";

        var response = await client.PostAsync("/graphql", new StringContent(mutation, Encoding.UTF8, "application/json"));

        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();
        var result = JsonConvert.DeserializeObject<GraphQLResponse>(content);

        Assert.NotNull(result.Data);
        Assert.NotNull(result.Data["addPost"]);
        Assert.Equal("New Post", result.Data["addPost"]["title"]);
        Assert.Equal("This is a new post.", result.Data["addPost"]["content"]);
    }
}

Yukarıdaki örnekte, AddPost mutasyonunu çağıran bir Integration Test bulunmaktadır. WebApplicationFactory kullanılarak test sunucusu oluşturulur ve HTTP isteği gönderilir. Cevap, beklenen sonuçlarla karşılaştırılarak doğrulanır.

2. Unit Testing:

Unit Testing, API’nin belirli bir parçasını (genellikle bir metod veya fonksiyon) izole bir şekilde test etmek için kullanılır. API’nin bağımlılıkları mocklanarak, test edilmek istenen metodun beklenen davranışını doğrulamak mümkün olur.

Adımlar:
  1. Bağımlılıkları Mocklama: Test edilecek metodun bağımlılıklarını mocklayarak, bu bağımlılıkların gerçek sistemlerin yerine geçmesini sağlayın.
  2. GraphQL Mutasyonunu Çağırma: Mocklanmış bağımlılıklar aracılığıyla GraphQL mutasyonunu çağırın ve metodun beklenen davranışını doğrulayın.
Örnek Kod:
public class MutationTests
{
    [Fact]
    public async Task AddPost_ReturnsCreatedPost()
    {
        // Arrange
        var repositoryMock = new Mock<IBlogRepository>();
        repositoryMock.Setup(repo => repo.AddPost(It.IsAny<Post>()))
                      .ReturnsAsync((Post p) => p); // Eklenen gönderiyi aynı şekilde geri döndür

        var mutation = new Mutation(repositoryMock.Object);
        var input = new AddPostInput { Title = "New Post", Content = "This is a new post." };

        // Act
        var result = await mutation.AddPost(input);

        // Assert
        Assert.NotNull(result);
        Assert.Equal("New Post", result.Title);
        Assert.Equal("This is a new post.", result.Content);
    }
}

Yukarıdaki örnekte, AddPost mutasyonunu test etmek için bir Unit Test bulunmaktadır. IBlogRepository bağımlılığı mocklanmıştır ve AddPost metodunun beklenen davranışını doğrulamak için kullanılmıştır.

Bu adımları takip ederek, ASP.NET Core Web API projenizdeki GraphQL mutasyonlarını test edebilir ve API’nizin beklenen davranışlarını doğrulayabilirsiniz. Bu, API’nizin güvenliğini sağlamak ve hataları hızlıca tespit etmek için önemlidir.

Mutation to update data

“Mutation to update data” başlığı altında, ASP.NET Core Web API projenizde GraphQL kullanarak veri güncellemek için bir mutasyon tanımlamanın adımlarını ve örneklerini gösterebilirim.

  1. Mutasyon Metodunu Tanımlama: İlk adım olarak, güncellenecek veriye uygun bir mutasyon metodu tanımlayın. Örneğin, bir blog uygulamasında bir gönderiyi güncellemek için bir mutasyon tanımlayabilirsiniz.
public class Mutation
{
    private readonly BlogRepository _repository;

    public Mutation(BlogRepository repository)
    {
        _repository = repository;
    }

    public async Task<Post> UpdatePost(int id, UpdatePostInput input)
    {
        // Gönderi veritabanından bul
        var existingPost = await _repository.GetPostById(id);

        if (existingPost == null)
        {
            throw new ArgumentException("Post not found", nameof(id));
        }

        // Gönderi bilgilerini güncelle
        existingPost.Title = input.Title ?? existingPost.Title;
        existingPost.Content = input.Content ?? existingPost.Content;

        // Veritabanına güncelleme yap
        await _repository.UpdatePost(existingPost);

        return existingPost;
    }
}

Yukarıdaki örnekte, UpdatePost adında bir mutasyon metodu tanımlanmıştır. Bu metot, güncellenecek gönderinin kimliğini (id) ve güncellenecek verileri (input) alır. Mevcut gönderi veritabanından alınır ve veriler güncellenir. Son olarak, güncellenmiş gönderi veritabanına kaydedilir ve geri döndürülür.

  1. Giriş Tipini Tanımlama: Mutasyonun parametrelerini tanımlamak için bir giriş tipi (input type) tanımlayın.
public class UpdatePostInput
{
    public string Title { get; set; }
    public string Content { get; set; }
}

Yukarıdaki örnekte, UpdatePostInput adında bir giriş tipi tanımlanmıştır. Bu, UpdatePost mutasyonunun parametrelerini belirtir.

  1. GraphQL Şemasını Güncelleme: Mutasyonu GraphQL şemanıza ekleyin, böylece istemciler tarafından kullanılabilir hale gelir.
public class MutationType : ObjectType<Mutation>
{
    protected override void Configure(IObjectTypeDescriptor<Mutation> descriptor)
    {
        descriptor.Field(m => m.UpdatePost(default, default))
                  .Argument("id", a => a.Type<NonNullType<IntType>>())
                  .Argument("input", a => a.Type<NonNullType<UpdatePostInputType>>())
                  .Type<NonNullType<PostType>>(); // Güncellenen gönderiyi döndür
    }
}

Yukarıdaki kodda, UpdatePost mutasyonunu MutationType sınıfına ekledik. UpdatePost mutasyonunun bir kimlik (id) ve bir giriş parametresi (input) alacağını ve bir PostType nesnesi döndüreceğini belirttik.

Bu adımları takip ettikten sonra, ASP.NET Core Web API projenizdeki GraphQL mutasyonları aracılığıyla veri güncellemek için bir mutasyon tanımlamış olursunuz. Artık istemciler, API’nize GraphQL sorguları aracılığıyla veri güncelleyebilirler.

Update data: Testing

“Update data: Testing” konusunda, ASP.NET Core Web API projenizdeki GraphQL mutasyonlarını (veri güncelleme) test etmek için Integration Testing ve Unit Testing olmak üzere iki ana yöntem bulunmaktadır.

1. Integration Testing:

Integration Testing, API’nizin tüm çalışma ortamını test etmek için kullanılır. Gerçek HTTP istekleri gönderilir ve API’nin davranışı gerçek bir ortamda doğrulanır. Bu, API’nin tüm katmanlarının (routing, controller, GraphQL sorgu işleme vb.) doğru çalıştığından emin olmanıza olanak tanır.

Adımlar:
  1. Test Ortamını Ayarlama: Testleriniz için bir test sunucusu oluşturun ve API’nizi bu sunucuda başlatın.
  2. GraphQL Mutasyonunu Çağırma: Oluşturulan test sunucusuna gerçek HTTP istekleri göndererek GraphQL mutasyonunu çağırın.
  3. Cevapları Kontrol Etme: API’nin geri döndürdüğü cevapları kontrol edin ve beklenen sonuçları doğrulayın.
Örnek Kod:
public class GraphQLIntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    public GraphQLIntegrationTests(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task UpdatePost_ReturnsUpdatedPost()
    {
        var client = _factory.CreateClient();

        var mutation = @"
            mutation {
                updatePost(id: 1, input: { title: ""Updated Title"", content: ""Updated Content"" }) {
                    id
                    title
                    content
                }
            }";

        var response = await client.PostAsync("/graphql", new StringContent(mutation, Encoding.UTF8, "application/json"));

        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();
        var result = JsonConvert.DeserializeObject<GraphQLResponse>(content);

        Assert.NotNull(result.Data);
        Assert.NotNull(result.Data["updatePost"]);
        Assert.Equal("Updated Title", result.Data["updatePost"]["title"]);
        Assert.Equal("Updated Content", result.Data["updatePost"]["content"]);
    }
}

Yukarıdaki örnekte, UpdatePost mutasyonunu çağıran bir Integration Test bulunmaktadır. WebApplicationFactory kullanılarak test sunucusu oluşturulur ve HTTP isteği gönderilir. Cevap, beklenen sonuçlarla karşılaştırılarak doğrulanır.

2. Unit Testing:

Unit Testing, API’nin belirli bir parçasını (genellikle bir metod veya fonksiyon) izole bir şekilde test etmek için kullanılır. API’nin bağımlılıkları mocklanarak, test edilmek istenen metodun beklenen davranışını doğrulamak mümkün olur.

Adımlar:
  1. Bağımlılıkları Mocklama: Test edilecek metodun bağımlılıklarını mocklayarak, bu bağımlılıkların gerçek sistemlerin yerine geçmesini sağlayın.
  2. GraphQL Mutasyonunu Çağırma: Mocklanmış bağımlılıklar aracılığıyla GraphQL mutasyonunu çağırın ve metodun beklenen davranışını doğrulayın.
Örnek Kod:
public class MutationTests
{
    [Fact]
    public async Task UpdatePost_ReturnsUpdatedPost()
    {
        // Arrange
        var repositoryMock = new Mock<IBlogRepository>();
        repositoryMock.Setup(repo => repo.GetPostById(It.IsAny<int>()))
                      .ReturnsAsync(new Post { Id = 1, Title = "Old Title", Content = "Old Content" });

        var mutation = new Mutation(repositoryMock.Object);
        var input = new UpdatePostInput { Title = "Updated Title", Content = "Updated Content" };

        // Act
        var result = await mutation.UpdatePost(1, input);

        // Assert
        Assert.NotNull(result);
        Assert.Equal("Updated Title", result.Title);
        Assert.Equal("Updated Content", result.Content);
    }
}

Yukarıdaki örnekte, UpdatePost mutasyonunu test etmek için bir Unit Test bulunmaktadır. IBlogRepository bağımlılığı mocklanmıştır ve UpdatePost metodunun beklenen davranışını doğrulamak için kullanılmıştır.

Bu adımları takip ederek, ASP.NET Core Web API projenizdeki GraphQL mutasyonlarını test edebilir ve API’nizin beklenen davranışlarını doğrulayabilirsiniz. Bu, API’nizin güvenliğini sağlamak ve hataları hızlıca tespit etmek için önemlidir.

Mutation to delete data

  1. Mutasyon Metodunu Tanımlama: İlk adım olarak, silinecek veriye uygun bir mutasyon metodu tanımlayın. Örneğin, bir blog uygulamasında bir gönderiyi silmek için bir mutasyon tanımlayabilirsiniz.
public class Mutation
{
    private readonly BlogRepository _repository;

    public Mutation(BlogRepository repository)
    {
        _repository = repository;
    }

    public async Task<int> DeletePost(int id)
    {
        // Gönderiyi veritabanından sil
        var deletedCount = await _repository.DeletePost(id);

        return deletedCount;
    }
}

Yukarıdaki örnekte, DeletePost adında bir mutasyon metodu tanımlanmıştır. Bu metot, silinecek gönderinin kimliğini (id) alır. Veritabanından gönderi silinir ve silinen gönderi sayısı döndürülür.

  1. GraphQL Şemasını Güncelleme: Mutasyonu GraphQL şemanıza ekleyin, böylece istemciler tarafından kullanılabilir hale gelir.
public class MutationType : ObjectType<Mutation>
{
    protected override void Configure(IObjectTypeDescriptor<Mutation> descriptor)
    {
        descriptor.Field(m => m.DeletePost(default))
                  .Argument("id", a => a.Type<NonNullType<IntType>>())
                  .Type<IntType>(); // Silinen gönderi sayısını döndür
    }
}

Yukarıdaki kodda, DeletePost mutasyonunu MutationType sınıfına ekledik. DeletePost mutasyonunun bir kimlik (id) alacağını ve silinen gönderi sayısını döndüreceğini belirttik.

Bu adımları takip ettikten sonra, ASP.NET Core Web API projenizdeki GraphQL mutasyonları aracılığıyla veri silmek için bir mutasyon tanımlamış olursunuz. Artık istemciler, API’nize GraphQL sorguları aracılığıyla veri silebilirler.

Querying and Mutating Relational Data with GraphQL in .NET Web API

Adding relationship data

“Adding relationship data” konusu, GraphQL ile .NET Web API’da ilişkisel veri eklemeyi anlatır. Özellikle ilişkisel veri eklerken GraphQL şemasını nasıl tanımlayacağınızı ve ilişkili verileri nasıl ekleyeceğinizi açıklar. İlişkisel veri eklerken, mevcut nesneler arasındaki ilişkileri göz önünde bulundurmanız gerekir. Örneğin, bir blog uygulamasında bir gönderinin yazarı olan bir kullanıcıyı eklemeyi ele alalım.

  1. GraphQL Şemasını Güncelleme: İlk adım, GraphQL şemanızı güncellemektir. İlişkisel veriyi eklemek için mevcut nesneler arasındaki ilişkileri belirtmeniz gerekir. Bu durumda, UserType ve PostType arasındaki ilişkiyi tanımlamanız gerekecektir.
public class UserType : ObjectType<User>
{
    protected override void Configure(IObjectTypeDescriptor<User> descriptor)
    {
        descriptor.Field(u => u.Id)
                  .Type<NonNullType<IdType>>();

        descriptor.Field(u => u.Username)
                  .Type<NonNullType<StringType>>();

        // Kullanıcının gönderilerini ilişkilendir
        descriptor.Field(u => u.Posts)
                  .ResolveWith<UserResolvers>(u => u.GetPosts(default!, default!))
                  .Type<ListType<PostType>>(); // Kullanıcının gönderileri
    }
}

public class PostType : ObjectType<Post>
{
    protected override void Configure(IObjectTypeDescriptor<Post> descriptor)
    {
        descriptor.Field(p => p.Id)
                  .Type<NonNullType<IdType>>();

        descriptor.Field(p => p.Title)
                  .Type<NonNullType<StringType>>();

        descriptor.Field(p => p.Content)
                  .Type<NonNullType<StringType>>();

        // Gönderinin yazarını ilişkilendir
        descriptor.Field(p => p.Author)
                  .ResolveWith<PostResolvers>(p => p.GetAuthor(default!, default!))
                  .Type<NonNullType<UserType>>(); // Gönderinin yazarı
    }
}

Yukarıdaki örnekte, UserType ve PostType sınıflarını güncelledik. UserType için, kullanıcının gönderilerine erişmek için bir alan ekledik. PostType için ise, gönderinin yazarına erişmek için bir alan ekledik.

  1. Resolver’ları Tanımlama: Şemanızı güncelledikten sonra, ilişkili alanları çözümleyecek resolver’ları tanımlamanız gerekir. Bu, GraphQL sorgularıyla ilişkili verileri çözmenize olanak tanır.
public class UserResolvers
{
    public async Task<IEnumerable<Post>> GetPosts(User user, [Service] BlogRepository repository)
    {
        return await repository.GetPostsByUserId(user.Id);
    }
}

public class PostResolvers
{
    public async Task<User> GetAuthor(Post post, [Service] BlogRepository repository)
    {
        return await repository.GetUserById(post.AuthorId);
    }
}

Yukarıdaki örnekte, UserResolvers ve PostResolvers sınıflarını tanımladık. GetPosts metodu, belirli bir kullanıcının gönderilerini alırken GetAuthor metodu, belirli bir gönderinin yazarını alır. Bu metotlar, veritabanından ilgili verileri almak için kullanılır.

Bu adımları takip ettikten sonra, .NET Web API’nizde GraphQL ile ilişkisel veri eklemiş olursunuz. Artık kullanıcıları ve gönderileri birbirine bağlayabilir ve GraphQL sorgularıyla ilişkili verileri alabilirsiniz.

Query to get relational data

“Query to get relational data” konusu, GraphQL ile .NET Web API’da ilişkisel verileri almayı anlatır. Özellikle GraphQL sorgularıyla birlikte ilişkili verileri almak için nasıl bir sorgu tanımlayacağınızı açıklar. Örneğin, bir blog uygulamasında bir kullanıcının gönderilerini almak için bir sorgu tanımlayalım.

  1. GraphQL Şemasını Güncelleme: İlk adım, GraphQL şemanızı güncellemektir. İlişkisel verileri almak için mevcut nesneler arasındaki ilişkileri belirtmeniz gerekir. Bu durumda, UserType ve PostType arasındaki ilişkiyi tanımlamanız gerekecektir.
public class UserType : ObjectType<User>
{
    protected override void Configure(IObjectTypeDescriptor<User> descriptor)
    {
        descriptor.Field(u => u.Id)
                  .Type<NonNullType<IdType>>();

        descriptor.Field(u => u.Username)
                  .Type<NonNullType<StringType>>();

        // Kullanıcının gönderilerini ilişkilendir
        descriptor.Field(u => u.Posts)
                  .ResolveWith<UserResolvers>(u => u.GetPosts(default!, default!))
                  .Type<ListType<PostType>>(); // Kullanıcının gönderileri
    }
}

public class PostType : ObjectType<Post>
{
    protected override void Configure(IObjectTypeDescriptor<Post> descriptor)
    {
        descriptor.Field(p => p.Id)
                  .Type<NonNullType<IdType>>();

        descriptor.Field(p => p.Title)
                  .Type<NonNullType<StringType>>();

        descriptor.Field(p => p.Content)
                  .Type<NonNullType<StringType>>();

        // Gönderinin yazarını ilişkilendir
        descriptor.Field(p => p.Author)
                  .ResolveWith<PostResolvers>(p => p.GetAuthor(default!, default!))
                  .Type<NonNullType<UserType>>(); // Gönderinin yazarı
    }
}

Yukarıdaki örnekte, UserType ve PostType sınıflarını güncelledik. UserType için, kullanıcının gönderilerine erişmek için bir alan ekledik. PostType için ise, gönderinin yazarına erişmek için bir alan ekledik.

  1. Resolver’ları Tanımlama: Şemanızı güncelledikten sonra, ilişkili alanları çözümleyecek resolver’ları tanımlamanız gerekir. Bu, GraphQL sorgularıyla ilişkili verileri çözmenize olanak tanır.
public class UserResolvers
{
    public async Task<IEnumerable<Post>> GetPosts(User user, [Service] BlogRepository repository)
    {
        return await repository.GetPostsByUserId(user.Id);
    }
}

public class PostResolvers
{
    public async Task<User> GetAuthor(Post post, [Service] BlogRepository repository)
    {
        return await repository.GetUserById(post.AuthorId);
    }
}

Yukarıdaki örnekte, UserResolvers ve PostResolvers sınıflarını tanımladık. GetPosts metodu, belirli bir kullanıcının gönderilerini alırken GetAuthor metodu, belirli bir gönderinin yazarını alır. Bu metotlar, veritabanından ilgili verileri almak için kullanılır.

  1. GraphQL Sorgusu Tanımlama: Son olarak, ilişkili verileri almak için bir GraphQL sorgusu tanımlayın.
query {
  user(id: 1) {
    id
    username
    posts {
      id
      title
      content
      author {
        id
        username
      }
    }
  }
}

Yukarıdaki örnekte, belirli bir kullanıcının (id: 1) kimlik bilgilerini ve gönderilerini almak için bir GraphQL sorgusu tanımladık. Sorgumuzda kullanıcının gönderileri ve her gönderinin yazarı da bulunmaktadır.

Bu adımları takip ettikten sonra, .NET Web API’nizde GraphQL ile ilişkisel verileri alabilir ve istemcilere ilişkili verileri sunabilirsiniz. Bu, GraphQL’in gücünden yararlanarak verileri etkili bir şekilde sorgulamanıza ve sunmanıza olanak tanır.

Get relational data: Testing

“Get relational data: Testing” konusu, GraphQL ile .NET Web API’da ilişkisel verileri almayı test etmek için nasıl bir test senaryosu oluşturulacağını açıklar. Bu senaryo, GraphQL sorgularıyla ilişkili verilerin doğru bir şekilde alınıp alınmadığını doğrulamak için kullanılır. İlişkisel veri alımını test etmek için, Integration Testing yöntemini kullanacağız

  1. Test Ortamını Ayarlama: İlk olarak, test ortamınızı oluşturun ve API’nizi test etmek için bir test sunucusu başlatın.
  2. GraphQL Sorgusunu Tanımlama: İlişkili verileri almak için bir GraphQL sorgusu tanımlayın. Bu sorgu, ilişkili verilerin doğru bir şekilde alınıp alınmadığını kontrol etmek için kullanılacaktır.
  3. Sorguyu Gönderme ve Cevabı Kontrol Etme: Tanımladığınız GraphQL sorgusunu test sunucusuna gönderin ve cevabı kontrol edin. İlişkili verilerin doğru bir şekilde alınıp alınmadığını doğrulayın.

İşte bu adımları daha ayrıntılı olarak açıklayan bir kod örneği:

public class GraphQLIntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    public GraphQLIntegrationTests(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task GetUserWithPosts_ReturnsUserWithPosts()
    {
        // Arrange
        var client = _factory.CreateClient();
        var query = @"
            query {
              user(id: 1) {
                id
                username
                posts {
                  id
                  title
                  content
                  author {
                    id
                    username
                  }
                }
              }
            }";

        // Act
        var response = await client.PostAsync("/graphql", new StringContent(query, Encoding.UTF8, "application/json"));
        response.EnsureSuccessStatusCode();
        var content = await response.Content.ReadAsStringAsync();
        var result = JsonConvert.DeserializeObject<GraphQLResponse>(content);

        // Assert
        Assert.NotNull(result.Data);
        Assert.NotNull(result.Data["user"]);
        Assert.NotNull(result.Data["user"]["posts"]);
        Assert.NotEmpty(result.Data["user"]["posts"]);
        Assert.NotNull(result.Data["user"]["posts"][0]["author"]);
    }
}

Yukarıdaki örnek kod, GraphQL sorgularıyla ilişkili verilerin doğru bir şekilde alınıp alınmadığını test etmek için bir Integration Test içerir. Bu test, belirli bir kullanıcının gönderilerini almak için bir GraphQL sorgusu gönderir ve alınan cevabı doğrular. İlişkili verilerin (kullanıcı, gönderiler ve gönderinin yazarı) doğru bir şekilde alındığını doğrulamak için cevap incelenir.

Bu test senaryosu, GraphQL ile .NET Web API’da ilişkisel verilerin alınmasını doğrulamak için etkili bir yöntemdir. Bu sayede, API’nizin istemcilere doğru veri sağladığından emin olabilirsiniz.

Mutation to add relational data

“Mutation to add relational data” konusu, GraphQL ile .NET Web API’da ilişkisel veri eklemeyi anlatır. Özellikle, ilişkili veri eklemek için bir mutasyon tanımlamanın adımlarını ve örneklerini gösterebiliriz. Örneğin, bir blog uygulamasında yeni bir gönderi eklerken bu gönderinin hangi kullanıcıya ait olduğunu belirten bir mutasyon tanımlayalım.

  1. Mutasyon Metodunu Tanımlama: İlk adım olarak, yeni bir gönderi eklemek için bir mutasyon metodu tanımlayın. Bu mutasyon metodu, yeni gönderinin başlığı, içeriği ve ait olduğu kullanıcının kimliği gibi bilgileri alarak veritabanına ekleyecektir.
public class Mutation
{
    private readonly BlogRepository _repository;

    public Mutation(BlogRepository repository)
    {
        _repository = repository;
    }

    public async Task<int> AddPost(AddPostInput input)
    {
        var postId = await _repository.AddPost(input.Title, input.Content, input.UserId);
        return postId;
    }
}

Yukarıdaki örnekte, AddPost adında bir mutasyon metodu tanımlanmıştır. Bu metot, AddPostInput adında bir girdi parametresi alır ve bu girdiye göre yeni bir gönderi ekler. input.UserId kullanarak gönderinin ait olduğu kullanıcının kimliğini alır.

  1. GraphQL Şemasını Güncelleme: Şemanızı güncelleyerek yeni mutasyonu ekleyin, böylece istemciler tarafından kullanılabilir hale gelir.
public class MutationType : ObjectType<Mutation>
{
    protected override void Configure(IObjectTypeDescriptor<Mutation> descriptor)
    {
        descriptor.Field(m => m.AddPost(default))
                  .Argument("input", a => a.Type<NonNullType<AddPostInputType>>())
                  .Type<IntType>(); // Eklenen gönderinin kimliğini döndür
    }
}

Yukarıdaki kodda, AddPost mutasyonunu MutationType sınıfına ekledik. AddPost mutasyonunun bir girdi parametresi olan input alacağını ve eklenen gönderinin kimliğini döndüreceğini belirttik.

  1. GraphQL Giriş Tipini Tanımlama: Mutasyonun girdi tipini tanımlayın.
public class AddPostInputType : InputObjectType<AddPostInput>
{
    protected override void Configure(IInputObjectTypeDescriptor<AddPostInput> descriptor)
    {
        descriptor.Field(p => p.Title)
                  .Type<NonNullType<StringType>>();

        descriptor.Field(p => p.Content)
                  .Type<NonNullType<StringType>>();

        descriptor.Field(p => p.UserId)
                  .Type<NonNullType<IntType>>();
    }
}

Yukarıdaki örnekte, AddPostInputType adında bir girdi tipi tanımlanmıştır. Bu girdi tipi, yeni bir gönderi eklemek için gereken başlık, içerik ve kullanıcı kimliği gibi bilgileri içerir.

Bu adımları takip ettikten sonra, .NET Web API’nizde GraphQL ile ilişkili veri eklemiş olursunuz. Artık istemciler, API’nize GraphQL sorguları aracılığıyla ilişkili veriler ekleyebilirler.

Add relational data: Testing

“Add relational data: Testing” konusu, GraphQL ile .NET Web API’da ilişkisel veri eklemeyi test etmek için nasıl bir test senaryosu oluşturulacağını açıklar. Bu senaryo, belirli bir GraphQL mutasyonunu çağırarak yeni ilişkisel verinin başarıyla eklenip eklenmediğini doğrulamak için kullanılır.

  1. Test Ortamını Ayarlama: İlk adım, test ortamınızı hazırlamaktır. Bu, API’nizi test etmek için bir test sunucusu oluşturmayı ve gerektiğinde temiz bir veritabanı ortamı oluşturmayı içerir.
  2. GraphQL Mutasyonunu Tanımlama: Test senaryosunda, yeni ilişkisel veriyi eklemek için kullanılacak olan GraphQL mutasyonunu tanımlamanız gerekir. Örneğin, yeni bir gönderi eklemek için bir mutasyon tanımlayabiliriz.
  3. Mutasyonu Gönderme ve Cevabı Kontrol Etme: Tanımladığınız GraphQL mutasyonunu test sunucusuna gönderin ve gelen cevabı kontrol edin. Eklenen verinin beklendiği gibi veritabanına yansıtıldığını ve cevabın doğru olduğunu doğrulayın.

İşte bu adımları daha ayrıntılı olarak açıklayan bir kod örneği:

public class GraphQLIntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    public GraphQLIntegrationTests(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task AddPost_ReturnsNewPostId()
    {
        // Arrange
        var client = _factory.CreateClient();
        var mutation = @"
            mutation {
              addPost(input: {
                title: ""New Post Title"",
                content: ""New Post Content"",
                userId: 1
              })
            }";

        // Act
        var response = await client.PostAsync("/graphql", new StringContent(mutation, Encoding.UTF8, "application/json"));
        response.EnsureSuccessStatusCode();
        var content = await response.Content.ReadAsStringAsync();
        var result = JsonConvert.DeserializeObject<GraphQLResponse>(content);

        // Assert
        Assert.NotNull(result.Data);
        Assert.NotNull(result.Data["addPost"]);
        var newPostId = int.Parse(result.Data["addPost"].ToString());
        Assert.True(newPostId > 0); // Yeni gönderinin kimliği geçerli bir pozitif tamsayı olmalıdır
    }
}

Yukarıdaki örnek kod, GraphQL mutasyonunu test etmek için bir Integration Test içerir. Bu test, belirli bir kullanıcıya ait yeni bir gönderi eklemek için bir GraphQL mutasyonu gönderir ve gelen cevabı doğrular. Eklenen verinin beklendiği gibi veritabanına yansıtıldığını ve dönen cevabın doğru olduğunu doğrulamak için cevap incelenir.

Bu test senaryosu, GraphQL ile .NET Web API’da ilişkisel veri eklemenin doğru çalıştığını doğrulamanıza yardımcı olur. Bu sayede, API’nizin istemcilere doğru şekilde veri eklediğinden emin olabilirsiniz.

Karanlıktan korkan bir çocuğu kolayca affedebiliriz. Hayatın gerçek trajedisi büyükler ışıktan korktuğunda başlar.

Plato

Bir sonraki yazıda görüşmek dileğiyle!”

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir


4 + 3 = ?