GraphQL Nedir?
GraphQL, clientlar ve serverlar (istemciler - sunucular) arasında iletişimi kolaylaştırmak için tasarlanmış bir API sorgu dilidir. Kullanıcının responsda (alacağı yanıtta) hangi verileri istediğini belirtmesini sağlar, bazen REST API'lerde görülebilen büyük yanıtlardan ve çoklu çağrılardan GraphQL sayesinde uzak durabiliyorsunuz.
GraphQL servisleri, bir istemcinin bir sunucuyla iletişim kurabileceği bir sözleşme tanımlar. İstemcinin verilerin nerede olduğunu bilmesine gerek yoktur. Bunun yerine, istemciler GraphQL sunucusuna sorgular gönderir ve bu da verileri artık neredelerse getirir. GraphQL platform bağımsız olduğundan, çok çeşitli programlama dilleriyle kullanılabilir ve neredeyse bütün data storelarla (veritabanı havuzları veya veri depoları diyebiliriz) iletişim kurmak için kullanılabilir.
GraphQL Nasıl Çalışır?
GraphQL şemaları, servisin verilerinin yapısını tanımlar ve mevcut nesneleri (types olarak bilinir veri tipi diyebiliriz), alanları ve ilişkileri listeler.
Bir GraphQL şeması tarafından tanımlanan veriler, üç tür işlem kullanılarak değiştirilebilir:
- Sorgulamalar (Queries) veri getirir.
- (Mutations) veri ekler, değiştirir veya kaldırır.
- Abonelikler (Subscriptions), sorgulamalara benzerdir, ancak sunucunun belirtilen biçimde verileri proaktif olarak bir istemciye gönderebileceği kalıcı bir bağlantı kurar.
GraphQL servisleri genellikle işlemlere istenen yapıda bir JSON nesnesi ile yanıt verir.
GraphQL Şeması Nedir?
GraphQL'de şema, servisin front-end ve backendi arasındaki bir sözleşmeyi temsil eder. İnsan tarafından okunabilen bir şema tanımlama dili kullanarak mevcut verileri bir dizi veri tipi olarak tanımlar. Bu veri tipleri daha sonra bir servis tarafından işlenebilir.
Tanımlanan tiplerin çoğu nesne tipidir. Bunlar, mevcut nesneleri ve sahip oldukları alan ve parametreleri tanımlar. Her alanın kendi tipi vardır ve bu tip başka bir nesne, skalar, enum, union, interface veya özel tip(custom type) olabilir.
Aşağıdaki örnek, Ürün tipi için basit bir şema tanımını göstermektedir. ! operatörü, alanın çağrıldığında null olamaz (yani boş olamaz değere sahip olmak zorunda) olduğunu gösterir.
Kod:
type Product {
id!: ID!
name: String!
description: String
price: Float!
}
Şemalar en az 1 sorgu içermelidir. Genellikle mevcut mutasyonların detaylarını da içerirler. (Mutation tanımı, GraphQL sunucuları üzerinde veri ekleme,silme veya güncelleme durumlarında kullanılır.)
GraphQL Sorguları Nedir?
GraphQL sorguları, veri deposundan veri getirir. REST API'deki GET istekleri gibidirler.
Sorgular genellikle aşağıdaki anahtar bileşenlere sahiptir:
- Sorgu işlemi türü. Bu teknik olarak isteğe bağlıdır, gelen isteğin bir sorgu olduğunu sunucuya açıkça söyler bu nedenle önerilir.
- Sorgu adı. Bu, istediğiniz herhangi bir şey olabilir. Sorgu adı isteğe bağlıdır, ancak hata ayıklamaya yardımcı olabileceği için önerilir.
- Veri yapısı. Bu, sorgu tarafından döndürülmesi gereken veridir.
- İsteğe bağlı olarak, bir veya daha fazla parametre. Bunlar, belirli bir nesnenin ayrıntılarını döndüren sorgular oluşturmak için kullanılır (örneğin "ID'si 123 olan ürünün adını ve açıklamasını bana ver").
Kod:
query myGetProductQuery {
product(id: 123) {
name
description
}
}
Tabii burada product type'ın şemada daha fazla alan içerebileceğini unutmayın. İhtiyacınız olan datayı isteyebiliyorsunuz bu da GraphQL'ı esnek kılan önemli bir özellik.
GraphQL Mutasyonları Nedir?
Mutasyonlar, verileri bir şekilde değiştirir, ekler, siler veya düzenler. REST API'nin POST, PUT ve DELETE metodları gibidirler.
Sorgular gibi, mutasyonların da döndürülen veriler için bir işlem türü, adı ve yapısı vardır. Ancak, mutasyonlar her zaman bir tür girdi alır. Bu, satır içi bir değer olabilir, ancak pratikte genellikle bir değişken olarak verilir.
Aşağıdaki örnek, yeni bir ürün oluşturmak ve ona ilişkin yanıtı gösteren bir mutasyonu göstermektedir. Bu durumda, servis yeni ürünlere otomatik olarak bir ID atayacak şekilde yapılandırılmıştır ve istendiği gibi döndürülmüştür.
Kod:
#Example mutation request
mutation {
createProduct(name: "Flamin' Cocktail Glasses", listed: "yes") {
id
name
listed
}
}
Kod:
#Example mutation response
{
"data": {
"createProduct": {
"id": 123,
"name": "Flamin' Cocktail Glasses",
"listed": "yes"
}
}
}
Sorgular ve Mutasyonların Bileşenleri
GraphQL syntaxi (sözdizimi), sorgular ve mutasyonlar için birkaç ortak bileşen içerir.
- Alanlar (Fields): Tüm GraphQL tipleri, field(alanlar) denilen sorgulanabilir veri öğeleri içerir. Bir sorgu veya mutasyon gönderdiğinizde, API'nin hangi alanları döndürmesini istediğinizi belirtirsiniz. Yanıt, istekte belirtilen içeriği yansıtır.
Kod:
#Request
query myGetEmployeeQuery {
getEmployees {
id
name {
firstname
lastname
}
}
}
Kod:
#Response
{
"data": {
"getEmployees": [
{
"id": 1,
"name" {
"firstname": "Carlos",
"lastname": "Montoya"
}
},
{
"id": 2,
"name" {
"firstname": "Peter",
"lastname": "Wiener"
}
}
]
}
}
Parametreler
Parametreler belirli alanlar için sağlanan değerlerdir. Bir tür için kabul edilebilecek parametreler şemada tanımlanır.
Parametreler içeren bir sorgu veya mutasyon gönderdiğinizde, GraphQL sunucusu; konfigürasyonuna göre nasıl yanıt vereceğini belirler. Örneğin, tüm nesnelerin ayrıntıları yerine belirli bir nesne döndürebilir.
Aşağıdaki örnek, çalışanın kimliğini parametre olarak alan bir getEmployee isteğini göstermektedir. Bu durumda, sunucu yalnızca bu id ile eşleşen çalışanın ayrıntılarıyla yanıt verir.
Kod:
#Example query with arguments
query myGetEmployeeQuery {
getEmployees(id:1) {
name {
firstname
lastname
}
}
}
Kod:
#Response to query
{
"data": {
"getEmployees": [
{
"name" {
"firstname": Carlos,
"lastname": Montoya
}
}
]
}
}
Değişkenler
Değişkenler, sorgunun kendisinde doğrudan değeri belli parametreler vermek yerine dinamik parametreler vermenizi sağlar.
Değişken tabanlı sorgular, satır içi parametreler kullanan sorgularla aynı yapıyı kullanır, ancak sorgunun belirli yönleri ayrı bir JSON tabanlı değişkenler sözlüğünden (json based variables dictionary) alınır. Sadece değişkenin kendi değeri değişirken ortak bir yapıyı birden çok sorgu arasında yeniden kullanmanıza olanak tanırlar.
Değişkenleri kullanan bir sorgu veya mutasyon oluştururken şunları yapmanız gerekir:
- Değişkeni ve türünü bildirin.
- Değişken adını sorgu içinde uygun yere ekleyin.
- Değişken değerini ve anahtarını değişken sözlüğünden(variable dictionary) geçirin.
Kod:
#Example query with variable
query getEmployeeWithVariable($id: ID!) {
getEmployees(id:$id) {
name {
firstname
lastname
}
}
}
Variables:
{
"id": 1
}
Bu örnekte, değişken ilk satırda ($id: ID!) ile tanımlanır. ! işareti, bu sorgu için gereken bir alan yani zorunlu olduğunu belirtir. Ardından, ikinci satırda (id:$id) ile bir parametre olarak kullanılır. Son olarak, değişkenin kendi değeri JSON değişken sözlüğünde ayarlanır. GraphQL nesneleri aynı adı taşıyan birden fazla özelliği içeremez. Örneğin, aşağıdaki sorgu geçersizdir çünkü ürün türünü iki kez döndürmeye çalışır.
Kod:
#Invalid query
query getProductDetails {
getProduct(id: 1) {
id
name
}
getProduct(id: 2) {
id
name
}
}
Aliase özelliği (takma adlar) API'nin döndürmesini istediğiniz özellikleri açıkça adlandırarak bu kısıtlamayı aşmanızı sağlar. Yani aynı türden nesnelerin birden fazla örneğini bir istekte döndürebilirsiniz. Bu, gereken API çağrılarının sayısını azaltmaya yardımcı olur.
Aşağıdaki örnekte, bu özelliği kullanarak her iki ürün için benzersiz bir adlandırma yapılmış. Bu sorguda artık bir sıkıntı çıkmaz.
Kod:
#Valid query using aliases
query getProductDetails {
product1: getProduct(id: "1") {
id
name
}
product2: getProduct(id: "2") {
id
name
}
}
Kod:
#Response to query
{
"data": {
"product1": {
"id": 1,
"name": "Juice Extractor"
},
"product2": {
"id": 2,
"name": "Fruit Overlays"
}
}
}
Fragments
Fragmentlar sorguların veya mutasyonların yeniden kullanılabilir parçalarıdır. İlgili türe ait alanların bir alt kümesini içerirler.
Bir kez tanımlandıktan sonra, sorgulara veya mutasyonlara dahil edilebilirler. Daha sonra değiştirilirlerse, değişiklik fragmentı çağıran her sorgu veya mutasyona dahil edilir.
Aşağıdaki örnek, ürün ayrıntılarının bir productInfo fragmentında yer aldığı getProduct sorgusunu gösterir.
Kod:
#Example fragment
fragment productInfo on Product {
id
name
listed
}
Kod:
#Query calling the fragment
query {
getProduct(id: 1) {
...productInfo
stock
}
}
Kod:
#Response including fragment fields
{
"data": {
"getProduct": {
"id": 1,
"name": "Juice Extractor",
"listed": "no",
"stock": 5
}
}
}
Abonelikler
Abonelikler, özel bir sorgu türüdür. İstemcilerin bir sunucu ile uzun süreli bir bağlantı kurmasını sağlar. Bu sayede sunucu verileri sürekli olarak sorgulamadan istemciye gerçek zamanlı güncellemeler gönderebilir. Abonelikler, öncelikle büyük nesnelerde küçük değişiklikler ve küçük gerçek zamanlı güncellemeler gerektiren fonksiyonlar (sohbet sistemleri veya kolaboratif düzenleme gibi) için yararlıdır. Normal sorgularda ve mutasyonlarda olduğu gibi, abonelik isteği döndürülecek verilerin şeklini tanımlar. Abonelikler genellikle WebSockets kullanılarak uygulanır.
Introspection
İntrospeksiyon GraphQL'da bulunan, bir sunucudan şema hakkında bilgi almaya yarayan bir fonksiyondur. Genellikle GraphQL IDE'leri ve dokümantasyon oluşturma toolları gibi uygulamalar tarafından kullanılır.
Normal sorgularda olduğu gibi, döndürülmesini istediğiniz yanıtın alanlarını ve yapısını belirtebilirsiniz. Örneğin, yanıtın yalnızca kullanılabilir mutasyonların adlarını içermesini isteyebilirsiniz.
İnrospeksiyon, potansiyel olarak hassas bilgilere (alan açıklamaları gibi) erişmek ve bir saldırganın API ile nasıl etkileşim kurabileceğini çözmesine yardımcı olabileceğinden dolayı ciddi bir sızıntı riski oluşturabilir. En iyisi inrospeksiyonun üretim ortamlarında devre dışı bırakılmasıdır.
GraphQL API açıkları ile ilgili bilgiler içeren bir diğer konumu da inceleyebilirsiniz:
GraphQL API vulnerabilities | GraphQL API Açıkları
GraphQL API açıkları GraphQL açıkları genellikle uygulama hatalarından ve tasarım kusurlarından kaynaklanır. Örneğin introspection özelliği açık bırakılmış olabilir, bu da saldırganların API'yi şema hakkında bilgi edinmek için sorgulamasına olanak tanır. GraphQL saldırıları, saldırganın veri...
www.turkhackteam.org
Kaynak: What is GraphQL? | Web Security Academy
Son düzenleme: