GraphQL with HotChocolate in ASP.NET Core
GraphQL with HotChocolate in ASP.NET Core
1. Konunun Mimari Önemi ve Temel Çalışma Prensipleri
GraphQL, API’lerin nasıl sorgulanması gerektiğini belirlemek için istemcilerin kendileri tarafından tanımladığı bir veri sorgulama dili ve sunucu tarafı çalışma zamanı olan bir API standardıdır. HotChocolate, .NET platformunda GraphQL uygulamalarını kolay bir şekilde geliştirmek için güçlü ve esnek bir araçtır. Bu makalede, GraphQL’in mimari önemi, temel çalışma prensipleri ve HotChocolate ile ASP.NET Core’da nasıl uygulanacağına dair detaylı bilgi vereceğiz.
2. Kurumsal Projelerde Dikkat Edilmesi Gereken En İyi Uygulamalar (Best Practices)
- Schema Tasarımı: GraphQL schema’ı, veri yapısını ve kullanılabilen sorguları tanımlar. İyi bir schema tasarımı, performansı artırır ve istemcilere esneklik sağlar.
- Veri Yükleme (Data Fetching): Veri yükleme stratejisi, performansı ve ölçeklenebilirliği etkiler. HotChocolate, veri yükleme stratejilerini yönetmek için çeşitli araçlar sunar.
- Yetkilendirme ve Güvenlik: Her GraphQL uç noktasının güvenliğini sağlamak önemlidir. HotChocolate, yetkilendirme politikalarını kolay bir şekilde tanımlamak için politika tabanlı yetkilendirme mekanizması sunar.
- Performans Optimizasyonu: Caching, sorgu optimizasyonu ve diğer performans iyileştirme teknikleri, GraphQL uygulamalarının etkinliğini artırır.
3. Gerçek Dünya Senaryolarına Uygun Kod Bloğu Örneği
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using HotChocolate;
using HotChocolate.AspNetCore;
using HotChocolate.Types;
using HotChocolate.Types.Relay;
namespace GraphQLWithHotChocolate
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.AddSubscriptionType<Subscription>()
.AddType<BookType>()
.AddType<AuthorType>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQL();
});
}
}
public class Query
{
[UsePaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<Book> GetBooks([Service] AppDbContext context) => context.Books;
}
public class Mutation
{
public Book AddBook([Service] AppDbContext context, AddBookInput input)
{
var book = new Book
{
Title = input.Title,
AuthorId = input.AuthorId
};
context.Books.Add(book);
context.SaveChanges();
return book;
}
}
public class Subscription
{
[Subscribe]
[Topic]
public Book OnBookAdded([EventMessage] Book book) => book;
}
public class BookType : ObjectType<Book>
{
protected override void Configure(IObjectTypeDescriptor<Book> descriptor)
{
descriptor.Field(t => t.Author)
.ResolveWith<Resolvers>(t => t.GetAuthorAsync(default, default));
}
private class Resolvers
{
public Task<Author> GetAuthorAsync(Book book, [Service] AppDbContext context)
{
return context.Authors.FindAsync(book.AuthorId);
}
}
}
public class AuthorType : ObjectType<Author>
{
protected override void Configure(IObjectTypeDescriptor<Author> descriptor)
{
descriptor.Field(t => t.Books)
.ResolveWith<Resolvers>(t => t.GetBooksAsync(default, default));
}
private class Resolvers
{
public Task<IReadOnlyList<Book>> GetBooksAsync(Author author, [Service] AppDbContext context)
{
return context.Books.Where(b => b.AuthorId == author.Id).ToListAsync();
}
}
}
public class AddBookInput
{
public string Title { get; set; }
public int AuthorId { get; set; }
}
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
}
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public List<Book> Books { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<Book> Books { get; set; }
public DbSet<Author> Authors { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
}
}
4. Performans Optimizasyonu ve Olası Darboğazlar
GraphQL uygulamalarının performansını optimize etmek için aşağıdaki stratejiler kullanılabilir:
- Caching: HotChocolate, sorgu sonuçlarını bellek, Redis gibi caching mekanizmalarında depolamak için destek sunar.
- Batching ve Query Optimization: Sorguları toplu olarak göndermek ve sorgu iyileştirme tekniklerini kullanmak, performansı artırır.
- Yetkilendirme ve Güvenlik: Güvenlik duvarları ve yetkilendirme politikaları, sorguların güvenliğini sağlar ve performansı etkileyebilir.
- Scalability: Uygulamanın ölçeklenebilirliği, performansı etkiler. HotChocolate, yüksek yük altında bile uygun performans sunar.





