Selamlar, bu blog yazımda siz değerli okurlarıma GraphQL ile sorgular nasıl yazılabilir ve daha etkili kullanım teknikleri nelerdir onlardan bahsedeceğim.
Örneklerimi github v4 apisi üzerinden anlatacağım.
İlk olarak davranış ilkelerinin isimlerini çektiğimiz basit bir sorgu ile başlayalım. Sol tarafta isteği sağ tarafta gelen cevabı görüyorsunuz. Gördüğünüz gibi birbirine oldukça benzeyen istek ve cevap.
Argümanlar
Github’ın v3 REST Api’sinde alttaki url, verilen username parametresine ait datayı dönüyordu. Klasik REST yapısı.
GET /users
GET /users/:username
Peki bu argüman paslama işini graphQL sorgumuzda nasıl yapacağız görelim.
username
dışında avatarUrl
‘e verilen size parametresi gibi graphQL ile her field’a (tanımlandıysa) argüman verebilirsiniz. Adeta fonksiyona parametre vermek gibi 😇
Nested
Topic
tipinde ki topic
, Topic
array tipinde relatedTopics
dönüyor. Tekerleme gibi oldu. Bunu birbiriyle ilişkili user’ın repoları, reponun sahibi, takımın üyeleri vs. gibi nested sorgu örnekleri ile de çoğaltabiliriz.
Alias
Aynı field’ları farklı argümanlarla çağırmaya çalıştığımızda aynı keyde iki data dönemediği için bir çakışma hatası fırlatır.
Bunu alias kullanarak çözebiliriz. Yine tek bir sorgu ile birden fazla sonuç alabildik.
Her field’a alias verebilirsiniz. Yukarıda adiSoyadi
örneğinde gördüğünüz gibi.
Fragment
Mesela yukarıdaki örnekte 3 kişinin datasına ulaştığım bir sorgu var. Sadece name alanına değil de birçok alana ihtiyacım olduğunu varsayalım. Bu da demek oluyor ki aynı şeyi 3 kez tekrar edeceğiz.
Şaka Şaka
user_datasi
adında User
tipi içine dağılmış, ihtiyaç halinde kullanılmak üzere bir fragment tanımladım. Sadece tekrarlı işler için değil, sorgularınızı yönetilebilir küçük parçalara bölmek için de fragmentları kullanabilirsiniz.
Değişkenler
Şu ana kadar ki sorgularda her şeyi sorgu içine yazdık. Ama çoğu uygulama da sorguya değişken vermemiz gereken durumlar oluşabilir.
- Sorgudaki statik değeri $degisken ile değiştir. (login: $name)
- $degisken öğesini, sorgu tarafından kabul edilen değişkenlerden biri olarak tanımlayın. ($name: String!)
- $degisken: değerini ayrı, ulaşıma özgü (genellikle JSON) değişkenler sözlüğüne geçirin. { “name”: “askn” }
Değişkenler hep $ ile başlamak zorundadır. Burada String! yanında ki ünlem o değişkenin zorunlu olduğunu ifade ediyor. ünlem konulmasaydı isteğe bağlı olurdu.
Tabii ki varsayılan bir değer ataması da yapabiliyoruz.
Bu örnek için sorgu denerken öğrendim ki, eğer zorunlu olarak tanımlanmışsa varsayılan değer ataması yapamıyormuşuz.
Non-null variable $name can't have a default value
Bu arada yukarıdaki örnekte user_data bir operation name. Anlamlı isimlerle kullanırsanız debug ve loglama konusunda size yardımı dokucaktır.
Bu sorgunun request payload’ına inspect element üzerinden baktığımızda şöyle atıldığını görüyoruz.
Yani sizde bunu curl gibi herhangi bir istemci kullanarak şu şekil atabilirsiniz.
$ curl 'https://..../bilobalabolo' \
-d '{
"operation_name": "user_data",
"query": "query user_data($name: String!){
user(login: $name) {
name
}
}",
"variables": {
"name": "askn"
}
}'
Burada bir aydınlanma molası verip bir çay içiniz.
Directives
Değişkenler ile daha dinamik sorgular yazabiliyoruz. Fakat yine de bazen tüm ihtiyacımızı görmediği durumlar oluyor.
Örneğin yukarıdaki sorgu için withFollowers
değişkeni aracılığı ile takipçi datasının gelip gelmeyeceğine karar verebiliriz.
@include(if: Boolean) Sadece true gelirse dahil edilsin
@skip(if: Boolean) Sadece false gelirse dahil edilsin.
Kendinizde mesela sadece ilk beş karakteri döndürecek custom directive tanımlayabilirsiniz.
Mutations
REST üzerinde get, post, put, delete methodlarından şimdiye kadar anlattıklarımın sadece GET ile alakalı olduğunu anlamışsınızdır. Peki ya data üzerinde değişiklik yapacağımız post, put, delete.
GraphQL üzerinde bu işlemler mutation’lar aracılığı ile yapılıyor.
Gördüğünüz gibi query ile neredeyse aynı yapıya sahip. addStar
mutation’ı argüman olarak starrableId almış ve
Starrable tipinde bir alan dönmüş. Tabii ki burada da değişkenleri sorgu içine yazmak yerine variable’ları kullanarak daha temiz bir yapı kurabilirsiniz.
Inline Fragments ve Meta Fields
GraphQL union type sistemine sahip. Yani dönecek data farklı tiplerde gelebilir. Bu tarz sorgularda inline fragment’ları kullanabiliriz.
Bu tarz durumlarda dönen verinin hangi tipte geldiğini client bilemez, bu yüzden nasıl davranacağını kestiremez. GraphQL ile __typename gibi değerin adını içeren meta field’lar bu konuda imdadımıza yetişiyor.
User veya Organization tipinde dönerse çağrılacak fieldları blok içinde yazdık.
Bu anlattıklarımın tamamı client tarafından sorguların graphql ile yazılmış bir sisteme nasıl atılacağı ile alakalı idi. “İyi de kardeşim bunun backend’i yok mu, bunca sorguyu nereye atacaklar?” dediğinizi duyar gibiyim. Meraklanmayın, diğer blog yazılarımda (Ruby ile) backend tarafını da aktaracağım.
Bu yazının tamamını okuma zahmetinde bulunduysanız siz de GraphQL’in tadına baktınız demektir. Yazıların devamı gelene dek şurada bekleyebilirsiniz.