.NET Core GraphQL
.NET Core ile GraphQL tabanlı web servis için gerekli olan paketlerin kurulumu, kullanımı ve GraphQL web servis oluşturma işlemi ile ilgili bilgiler yer alıyor.
GraphQL nedir?
GraphQL hakkında detaylı bilgi için GraphQL Nedir? yazıma bakabilirsin.
GraphQL kurulumu
İlk olarak .NET Core CLI ile web projesi oluşturalım.
dotnet new web -o GraphQLProjesi
Gerekli olan paketleri yükleyelim.
dotnet add package GraphQL
Paket şema(schema), sorgu(query) ve veri yapısı(type) oluşturmak için kullanılır.
dotnet add package GraphQL.Server.Transports.AspNetCore
Paket GraphQL şemasını .NET Core projesine middleware (orta-katman) olarak eklemek için kullanılır.
dotnet add package GraphQL.Server.Ui.Playground
Paket GraphQL sorgulama editörü için kullanılır.
NOT: GraphQL editör paketi GraphQL web servisini ek bir yazılıma ihtiyaç duymadan esnek bir şekilde sorgulamayı sağlar.
dotnet add package GraphQL.SystemTextJson
veya
dotnet add package GraphQL.NewtonsoftJson
Paket JSON işlemlerinde hangi paketin (System.Text.JSON veya Newtonsoft.Json) kullanılacağını belirler.
NOT: Visual Studio kullanılıyorsa Package Manager Console alanına dotnet add package yerine Install-Package yazılır.
GraphQL web servis oluşturma
GraphQL web servisi oluşturmak için ilk olarak bir şema belirlememiz gerekir.
Schema – Şema
Şema içerisinde Query, Mutation, Subscription yapıları yer alır.
public class AppSchema : GraphQL.Types.Schema {
public AppSchema(IServiceProvider serviceProvider) : base(serviceProvider) {
Query = serviceProvider.GetService<RootQuery>();
}
}
Şema GraphQL.Types.Schema sınıfından kalıtım alınarak yapılır.
Şema içerisinde yer alan Query, Mutation ve Subscription özelliklerine oluşturulan GraphQL sorguları(query), işlemleri(mutation) eklenir.
Yukarıda RootQuery sorgusunu şemaya eklemiş olduk.
Query – Sorgulama
GraphQL sorgularında yer alan alanlar ObjectGraphType sınıfındaki Field metodu ile belirlenir.
public class RootQuery : ObjectGraphType {
public RootQuery() {
Name = "RootQuery";
Description = "Burada Query açıklaması yer alabilir.";
Field<StringGraphType>("mesaj")
.Description("Burada alan ile ilgili açıklama yer alabilir.")
.Resolve(context => "Merhaba GraphQL!");
}
}
Alana ait veri yapısı için ön tanımlı veri yapıları kullanılabilir.
- StringGraphType
- IntGraphType
- FloatGraphType
- BooleanGraphType
- IdGraphType
- DateGraphType
- ListGraphType
Ayrıca ObjectGraphType sınıfı kullanılarak özel bir veri yapısı tanımlanabilir.
Field metodu sorguda yer alacak alan adını name, açıklamasını description ile belirler.
Resolve parametresi ise sorgu sonucu gönderilecek veriyi belirtir.
Resolve parametresi bir fonksiyon aldığından gönderilecek veri dosyadan, veritabanından alınarak fonksiyon dönüş değeri olarak gönderilir.
Şema ve sorgu hazırlandıktan sonra GraphQL şeması servis olarak eklenir.
var builder = WebApplication.CreateBuilder(args);
// GraphQL servisi eklenerek ayarlar yapılır
builder.Services.AddGraphQL(options => {
options.AddSystemTextJson();
options.AddSchema<AppSchema>();
options.AddGraphTypes();
});
var app = builder.Build();
// GraphQL servisine oluşturulan şema gönderilir.
app.UseGraphQL<AppSchema>();
// GraphQL editörü eklenir.
app.UseGraphQLPlayground();
app.MapGet("/", () => "Hello World!");
app.Run();
Ayarları yaptıktan sonra projeyi çalıştıralım.
dotnet run
veya
dotnet watch run
Proje çalıştırıldıktan sonra /ui/playground adresi ile GraphQL editörüne ulaşabiliriz.
Editörün sağ kısmında yer alan Schema ile şema bilgilerine, Docs ile Field metodu ile eklenen alanlara ve açıklamalarına ulaşabiliriz.
Editörün sol kısmında yer alan alana aşağıdaki sorguyu yazıp çalıştıralım.
{
mesaj
}
veya
query IlkSorgu {
mesaj
}
Sorgu çalıştırıldıktan sonra sağ kısımda aşağıdaki gibi bir sonuç görünecektir.
{
"data": {
"mesaj": "Merhaba GraphQL!"
}
}
RootQuery sorgusuna yeni bir alan ekleyelim.
Field<NonNullGraphType<IntGraphType>>("sayi")
.Description("Her bir istek sonucunda rastgele bir sayı üretecektir.")
.Resolve(context => Random.Shared.Next(0, 100));
Yukarıda yer alan NonNullGraphType ile sayi alanının null olmayacağını IntGraphType ile sonucun sayısal bir değer olacağını belirttik.
Sorgu sonucunu mesaj alanından farklı olarak Random sınıfı ile dinamik olarak oluşturduk.
GraphQL editörüne aşağıdaki sorguyu yazıp çalıştıralım.
query IkinciSorgu {
sayi
}
mesaj alanını da almak için sadece mesaj alanını eklemek yeterli olacaktır.
query IkinciSorgu {
sayi
mesaj
}
Type – Veri yapısı
.NET ve Java gibi platformların en önemli özelliği düzenli-mimari bir geliştirme yapmaya imkan vermesidir.
MVC içerisinde yer alan Model, Katmanlı mimaride kullanılan Data, Repository, Entities gibi kısımlarda uygulamaya ait veri yapısı-modeli belirlenir.
public class Person {
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string FullName => $"{FirstName} {LastName}";
}
Bu veri yapısını-modelini kullanarak GraphQL veri yapısı oluşturmak için ObjectGraphType sınıfına generic olarak geçmek yeterli olacaktır.
public class PersonType : GraphQL.Types.ObjectGraphType<Person> {
public PersonType() {
Field(p => p.ID).Description("Person ID");
Field(p => p.FirstName).Description("Person FirstName");
Field(p => p.LastName).Description("Person LastName");
Field(p => p.Email).Description("Person Email");
}
}
Veri yapısını kullanmak için RootQuery sorgusuna yeni bir alan ekleyelim.
Field<ListGraphType<PersonType>>("people")
.Resolve(context => new List<Person>(){
new Person{ID=1, FirstName="Yusuf", LastName="Sezer"},
new Person{ID=2, FirstName="Ramazan", LastName="Sezer"},
new Person{ID=3, FirstName="Sinan", LastName="Sezer"},
new Person{ID=4, FirstName="Mehmet", LastName="Sezer"}
});
Birden fazla değer olacağı için ListGraphType ve oluşturduğumuz veri yapısını(PersonType) kullandığımıza dikkat edin.
NOT: Gönderilecek değerler dosyadan, veritabanından veya başka bir kaynaktan alınabilir.
GraphQL editörüne aşağıdaki sorguyu yazıp çalıştıralım.
query UcuncuSorgu {
sayi
people {
firstName
lastName
}
}
Sorgu sonucunda sayi ve dizi halinde firstName, lastName değerleri listelenecektir.
Arguments – Argümanlar
GraphQL web servisine parametre göndermek için Arguments yapısı kullanılır.
Arguments yapısını kullanmak için Field metodunun arguments değerine gerekli argümanları yazmak yeterli olacaktır.
Argüman değeri context.GetArgument ile alınarak işlem yapılır.
Field<PersonType>("person")
.Argument<NonNullGraphType<IdGraphType>>("id")
.Resolve(context => {
var id = context.GetArgument<int>("id");
List<Person> people = new List<Person>() {
new Person{ID=1, FirstName="Yusuf", LastName="Sezer"},
new Person{ID=2, FirstName="Ramazan", LastName="Sezer"},
new Person{ID=3, FirstName="Sinan", LastName="Sezer"},
new Person{ID=4, FirstName="Mehmet", LastName="Sezer"}
};
Person? foundPerson = people.Find(p => p.ID == id);
if (foundPerson == null) {
context.Errors.Add(new GraphQL.ExecutionError("Person not found!"));
return null;
}
return foundPerson;
});
Örnekte Field metodu arguments ile argümanları belirledik ve parametre değerini resolve içerisinde context.GetArgument ile alarak arama işlemi yaptık.
Parametreye karşılık gelen bir değer bulunmadığı durumda context.Errors ile hata mesajı gönderdik.
Parametreye karşılık gelen bir değer bulunduğunda ise bulunan değeri gönderdik.
NOT: Tek değer gönderileceği için alan veri türü olarak sadece PersonType kullanıldığına dikkat edin.
GraphQL editörüne aşağıdaki sorguyu yazıp çalıştıralım.
query DorduncuSorgu {
sayi
person(id: 1) {
firstName
lastName
}
}
Parametre olarak olmayan bir değer yazıldığında context.Errors alanına eklenen hata gönderilecektir.
Mutations – İşlemler
Veri ekleme, silme ve güncelleme gibi işlemleri yapmak için Mutations yapısı kullanılır.
Mutations yapısı Query ve Arguments yapılarının bir benzeridir.
Mutations tanımlama işlemi Query tanımlama işleminde olduğu gibi aşağıdaki gibi yapılır.
public class RootMutation : GraphQL.Types.ObjectGraphType {
public RootMutation() {
Name = "RootMutation";
Description = "Burada Mutation açıklaması yer alır.";
}
}
Mutation şemaya eklenir.
public class AppSchema : GraphQL.Types.Schema {
public AppSchema(IServiceProvider serviceProvider) : base(serviceProvider) {
Query = serviceProvider.GetService<RootQuery>();
Mutation = serviceProvider.GetService<RootMutation>();
}
}
Mutation işlemleri Query ve Arguments yapısındaki gibi yapılır.
Field<StringGraphType>("addPerson")
.Description("Add new person.")
.Arguments(new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "firstName" },
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "lastName" })
.Resolve(context => {
var firstName = context.GetArgument<string>("firstName");
var lastName = context.GetArgument<string>("lastName");
System.IO.File.AppendAllText("person.txt", $"{firstName} {lastName} {System.Environment.NewLine}");
return "Başarılı";
});
Mutation yapısının kullanımı aşağıdaki gibidir.
mutation KisiEkle {
addPerson(firstName: "Yusuf", lastName: "Sezer")
}
İşlem sonrası person.txt dosyasına parametre olarak gönderilen değerler eklenecektir.
Mutations yapısındaki parametreleri ayrı ayrı belirlemek yerine aşağıdaki gibi yeni bir GraphQL veri yapısı oluşturulabilir.
public class PersonInputType : GraphQL.Types.InputObjectGraphType<Person> {
public PersonInputType() {
Field(p => p.FirstName);
Field(p => p.LastName);
}
}
NOT: Argümana ait veri yapısı için InputObjectGraphType sınıfının kullanıldığına dikkat edin.
Oluşturulan veri yapısı aşağıdaki gibi kullanılır.
Field<StringGraphType>("addPerson")
.Description("Add new person.")
.Argument<NonNullGraphType<PersonInputType>>("person")
.Resolve(context => {
var person = context.GetArgument<Person>("person");
System.IO.File.AppendAllText("person.txt", $"{person.FullName} {System.Environment.NewLine}");
return "Başarılı";
});
GraphQL web servisini kullanmak için GraphQL adresine aşağıdaki gibi bir istek göndermek yeterli olacaktır.
sunucu-adresi/graphql?query={mesaj}
Ancak Apollo Client, Relay gibi çeşitli araçları kullanmak daha esnek sorgular için faydalı olacaktır.
GraphQL Aliases, Fragments, Named Queries, Variables, Directives, Interfaces, Unions gibi özelliklere sahiptir.
Özellikler hakkında detaylı bilgi için aşağıdaki GraphQL sayfasına bakabilirsiniz.
https://graphql.org/learn
GrapQL örneğine buradan ulaşabilirsiniz.
.NET Derslerine buradan ulaşabilirsiniz.
Web Servis Derslerine buradan ulaşabilirsiniz…
Hayırlı günler dilerim.