🥊 Gato GraphQL vs WPGraphQL: the fight!
Güncelleme 01/05/2024: Gato GraphQL vs WPGraphQL karşılaştırmasına göz atın.
Bayanlarrrrrrrrrrr ve baylar.

Yüzyılın maçı için MGM Grand Garden Arena'ya hoş geldiniz! Bu gece tarih yazıyoruz. İki genç dövüşçü, bunca emek verdikleri ödül için ringe çıkacak:
"WordPress'te GraphQL" dünya şampiyonu olmak için 🏆
Sağımızda mevcut şampiyon var. Her ne kadar yalnızca 4 yaşında olsa da, çoktan deneyim kazandı; yakın zamanda 1.0 sürümüne ulaştı ve wp.org dizininde yayımlandı; kitleler arasında büyük popülerlik kazandı.
🥁 Alkış 🥁 lütfen 🥁 ...... WPGraphQL!

Solumuzda ise meydan okuyucu var. Dünyaya çıkalı henüz 1 ay oldu; ama son derece enerjik ve hırslı, gücünü ilk günden beri gösteriyor. Bugünkü karşılaşmayı talep eden oydu. Bu gece onun şansı; dünya izliyor.
🥁 Alkış 🥁 lütfen 🥁 ...... Gato GraphQL!

Bu gece iki rakibimiz, açılış zilinin çalmasını beklerken ringin ortasında ilk kez yüz yüze gelecek. Birbirlerinin zayıf noktalarını bulmaya çalışarak birbirlerini inceliyorlar. Ama ikisinden de tek bir şey yayılıyor: özgüven.

Kim galip gelecek? WPGraphQL, taraftarlarının desteğine dayanarak avantajını koruyacak mı? Yoksa yeni gelen Gato GraphQL, kitleleri kendi tarafına çeken bir hayranlık dalgasıyla şüpheci topluluğu yumruklarının gücüne inandıracak mı?
Bu gece, bayanlar ve baylar, öğreneceğiz.
Bahislerinizi yapın. Ve maçın keyfini çıkarın!
🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣
Kısa süre önce benden, kendi eklentim Gato GraphQL ile WPGraphQL arasındaki farkları açıklamamı istediler.
Her iki eklenti de WordPress için birer GraphQL sunucusudur, yani aynı amaca hizmet ederler. Ancak perde arkasında farklı özelliklere sahipler; bu da birini belirli bir davranış gereksinimini karşılamada diğerinden daha iyi yapabilir.
Kendi eklentim konusunda taraflı olduğumu kabul etsem de hem GraphQL hem WordPress açısından önemli bulduğum konulara dayalı adil bir karşılaştırma yapmaya çalıştım. (Okuyucular başka bir konu üzerinde karşılaştırma isterlerse memnuniyetle yaparım.)
Karşılaştırma kapsamlı değil. Örneğin, aynı GraphQL sorgusunun her iki sunucuyla çözümleme hızını ölçen bir kıyaslama da yapmak isterdim. (Okuyucular bu öneriyi ilgi çekici bulursa gelecek bir makale için yapabilirim.)
Karşılaştırmamı 4 ana alana böldüm: Popülerlik, Kod stili ve standartlar, Acil meseleler ve Kapsamı genişletmek; her birinde 3 madde olmak üzere toplamda 12 "round" oluştu. Sonunda jüri kararını açıklayarak şampiyonu ilan ediyor.
Doğrudan bir konuya atlamak için aşağıya tıklayın:
🔔 Ding 🔔 ding 🔔 diiiiiing...
Açılış zili çaldı...
Maç başladı!
Popülerlik
Herhangi bir yazılımın (ya da teknolojinin) insanlar tarafından kullanılması gerekir; aksi hâlde alternatiflere kıyasla daha iyi olması yalnızca bir anekdot olarak kalır.
Örneğin, daha hızlı yazmaya izin veren alternatifler olmasına karşın hâlâ ağırlıklı olarak QWERTY klavyeyi kullanıyoruz.
İki eklenti ne kadar popüler?
Round 1: Kim kullanıyor ve ne kadar eksiksiz
WPGraphQL, şimdiye kadar WordPress'te GraphQL ile eş anlamlıydı. Geliştirmeye başlandığı Kasım 2016'dan bu yana 4 yılı aşkın sürede repoda 2.800'den fazla yıldız topladı, 4.600'ü aşkın takipçiden oluşan bir topluluk oluşturdu ve projeye neredeyse 100 katkıda bulunan kişiyi cezbetti.
1.0 sürümüne ulaştı ve Kasım 2020'de wp.org eklenti dizinine yüklendi. O günden bu yana 8.000'in üzerinde aktif kuruluma ulaştı. Şu anda WordPress içeriğini Gatsby'ye kaynak yapmak için tek çözüm; daha yakın zamanda ise WPEngine'in Headless framework'ü ve WebDevStudios'un Next.js WordPress başlangıç şablonu dahil çeşitli projeler onu yığınlarına ekledi.
Kısacası, WPGraphQL popüler.
Gato GraphQL için geliştirme, yaklaşık 1,5 yıl önce (daha geniş bir projenin parçası olarak) ciddi biçimde başladı ve 6 ay önce "yeterince iyi" bir duruma ulaştı; o tarihten bu yana repoda 150 yıldız aldı. Eklenti şu anda 0.7 sürümündedir ve 1.0'a ulaşması için hâlâ birkaç ay var (örneğin şemada henüz kategoriler yok).
Geçen ay gatographql.com'u başlattım ve o tarihten bu yana eklentiyi blog üzerinden (tıpkı şu anda okuduğunuz makale gibi) tanıttım; ayrıca CSS-Tricks'te tanıtım makalesi yayımladım. Bu girişimler siteye birkaç yüz kişi çekti ve 100'den fazla ziyaretçi eklentiyi indirdi.
Kısacası, Gato GraphQL yavaş ama istikrarlı biçimde popülerlik kazanıyor ve hâlâ geliştirilmekte olan bir proje.
Round galibi: WPGraphQL.

Round 2: Eklenti kullanılabilirliği
Eklentiler, diğer WordPress eklentileriyle Gato GraphQL aracılığıyla etkileşim kurulmasını sağlar.
WPGraphQL'in ACF, WooCommerce, Yoast ve birkaç diğeri için eklentileri var.
Gato GraphQL'in henüz hiçbir eklentisi yok ve 1.0 sürümü yayımlanmadan önce çok fazla eklenti olmasını beklemiyorum.
Bununla birlikte, Gato GraphQL mimarisinde eklentilere büyük önem veriyor; kullanıcının bunları (etkinleştirme, devre dışı bırakma, yapılandırma ve belgelerini okuma) merkezi bir yerden, "Modules" sayfasından yönetmesine olanak tanıyor:

Kısacası, WPGraphQL zaten eklentilere sahipken Gato GraphQL onlar için zemin hazırlıyor.
Round galibi: WPGraphQL.

Round 3: Hedef kitle
WPGraphQL geliştiricileri hedefler: WordPress sitenizden veri çıkarmak istiyorsanız GraphQL sorgunuzu kodunuzun bir yerine (büyük ihtimalle bir JavaScript fonksiyonu içine) kaydetmeniz gerekir. Ardından bunu kullanabilmek için programlamada yeterince iyi olmanız gerekir.
Gato GraphQL ise herkesin kullanabilmesi gerektiği WordPress felsefesini benimser; teknik bilgisi olmayanlar da dahil. Bu hedefin gerçekleşmesi için WordPress editörü aracılığıyla GraphQL sorgusu oluşturup yönetmeyi mümkün kılıyor; böylece WordPress sitesinin verilerini bir API aracılığıyla erişilebilir hâle getirmek, bir blog yazısı oluşturmak kadar kolaylaşıyor.
Ayrıca Gato GraphQL, GraphQL hizmetiyle görsel biçimde etkileşim kurmak için istemci sunmaya daha fazla önem veriyor. Her iki eklenti de sorguyu çalıştırmak için GraphiQL istemcisini sağlarken yalnızca Gato GraphQL, şemayı etkileşimli olarak keşfetmek için Voyager istemcisini de sunuyor:

Round galibi: Gato GraphQL.

Kod stili ve standartlar
Koddan konuşalım!
GraphQL kullanıyorsanız büyük olasılıkla headless WordPress yapıyor ve siteyi modern bir paradigma olan JavaScript framework'ü ile render ediyorsunuzdur. Üstelik WordPress eski bir CMS olabilir; ama GraphQL, siteden veri erişimi için modern bir arayüzdür. Bu nedenle akıllı bir geliştirici olduğunuzu, zarif kod üretmekten zevk aldığınızı ve yetersiz bir çözümü kabul etmeyeceğinizi rahatlıkla varsayabilirim.
Bu iki eklentinin kodu (hem kendi kod tabanından hem de özel uygulamalardan beklenen) ne kadar zarif?
Round 4: PHP gereksinimleri
WPGraphQL ve Gato GraphQL'in ikisi de PHP 7.1+ gerektiriyor.
Ancak bir fark var: Gato GraphQL aslında PHP 7.4 kullanılarak kodlanmış ve ardından üretim için PHP 7.1'e transpile edilmiş.
Bu yüzden Gato GraphQL ile kod yazmak çok daha keyifli: object tipi, tipli özellikler ve arrow fonksiyonları dahil yeni PHP özelliklerini kullanabilirsiniz. PHP 8.0 desteği eklendiğinde (Lando'nun yeni sürümü yayımlandığında), union tipleri, match ifadesi ve diğerlerini de kullanabileceksiniz.
Round galibi: Gato GraphQL.

Round 5: Kodlama pratikleri
WPGraphQL ile başlayalım. wp-graphql/wp-graphql reposuna göz atıldığında dikkatimi çeken bir şey var:

Yakından bakıldığında:

Üzgünüm ama buna karşı tek bir tepkim var:

Composer'ın vendor klasörünü repoya commit etmek kötü bir pratiktir ve Composer bunu açıkça önermez.
Bu sorunu düzeltmek zor değil (hatta GitHub actions tabanlı bir yöntemi kendim anlattım); bu yüzden neden orada durduğunu merak ediyorum.
Bu roundda WPGraphQL kendine vuruyor diyebilirim!

Devam edelim. WPGraphQL için geliştirme yapmak, çok kapsamlı bir hook (action ve filter) koleksiyonunu bilmeyi gerektiriyor. WPGraphQL'in Geliştirici referansına göz atıldığında bu kapsamı takdir edebilirsiniz.
Action listesinin ekran görüntüsünü alabilmek için tarayıcımı %50'ye küçültmek zorunda kaldım:

Filter listesi için %30'a küçülttüm (Firefox'un desteklediği en düşük değer) ve yine de tüm listeyi alamadım:

Şimdi Gato GraphQL'i içeren monorepo olan GatoGraphQL/GatoGraphQL reposuna geçelim.
Kodun bazı özellikleri şunlar:
✅ PSR-1, PSR-4 ve PSR-12 standartlarıyla uyumlu.
✅ Tüm kod birden fazla atomik pakete bölünmüş; hepsi (eklenti için 100'den fazla, projenin tamamı için 200'den fazla) aynı monorepo'da barındırılıyor.
✅ Tüm bağımlılıkları yönetmek için Composer kullanıyor.
✅ Uygulamadaki tüm servisleri yönetmek için Symfony Dependency Injection kullanıyor. Yeni bir type resolver, field resolver veya directive resolver kaydetmek için container'a yeni bir servis kaydetmek yeterli.
✅ Her sınıf bir servis, Symfony Dependency Injection ise uygulamanın tamamını otomatik olarak bir araya getiriyor.
✅ Altta yatan GraphQL sunucusu CMS-agnostik. Gato GraphQL, WordPress için sözleşmeleri uygular ve biraz özel mantık ekler (örneğin istemcileri sağlamak için).
WordPress'e özgü kod, toplam kodun yalnızca yaklaşık %10'unu oluşturuyor. Bu %10'u başka bir framework veya CMS (Laravel/Drupal/vb.) için çoğaltmak, onlar için de bir GraphQL sunucusu uygulaması sağlayabilir.
✅ CMS-agnostik olmanın bir sonucu olarak, bir resolver kodlamak; yeniden kullanılabilir servislerin desteklediği genel iş mantığını kodlamak anlamına geliyor. Asla WordPress kodu açısından düşünmüyoruz ve teknik borçla nadiren uğraşmak zorunda kalıyoruz.
✅ Benzer şekilde, GraphQL şeması WordPress veri modelinin birebir kopyası değil; bu sayede WordPress'in veri katmanında biriktirdiği teknik borç atlatılıyor ve temiz bir arayüz sağlanıyor.
✅ GraphQL'in N+1 sorunu, mimari tasarım gereği gerçekleşemez ve geliştiriciye hiçbir yük bindirmez.
✅ Sunucu yalnızca bir GraphQL sunucusu değil: aslında bir API sunucusu; yanıt, tek bir doğruluk kaynağından başka formatlarda veya spesifikasyonlarda (örn. REST) da çıktılanabiliyor. (Bununla ilgili daha fazla bilgi 11. roundda.)
✅ Hiçbir vendor dizini commit edilmiyor. Bunun yerine kaynak kod, dağıtım koduna (yani WordPress sitesine kurulacak nihai eklentiye) GitHub actions aracılığıyla dönüştürülüyor ve vendor klasörünü içeren bir dist reposuna dağıtılıyor.
✅ Dağıtım için kod oluşturulurken PHP-Scoper ile kapsama alınıyor; PHP 7.4 kodu içeren kaynak kod ise PHP 7.1'e transpile ediliyor.
✅ Kapsama sorununu çözdüğü için eklenti herhangi bir üçüncü taraf bağımlılığına güvenebiliyor. Şu anda Symfony'nin DependencyInjection, Cache ve Dotenv, Guzzle (harici API'lerle etkileşim için), League'in Pipeline'ı ve birçok diğerini kullanıyor.
Bu yalnızca bugün için değil, gelecek için de önemli: Packagist deposundaki herhangi bir bağımlılığı kullanabileceğimden emin olabiliyorum; böylece tekerleği yeniden icat etmem gerekmiyor.
✅ Alanlar tiplere abone olur; bu da GraphQL şemasını kolayca genişletilebilir kılıyor.
Round galibi: Gato GraphQL (fark oldukça büyük, izin verirseniz bunu söyleyeyim).

Round 6: Şemayı genişletmek
GraphQL şemasına bir alan ekleyelim.
WPGraphQL için öğreticiye uyuyoruz. Önerilen kod aşağıdaki gibi. Bir diziyi bildiren fonksiyonu çalıştırmak için bir action hook tanımlıyor. Hem alanların açıklaması hem de çözümleme işlevi dizi içinde sağlanıyor:
add_action( 'graphql_register_types', function() {
register_graphql_field( 'RootQuery', 'myNewField', [
'type' => 'String',
'args' => [
'myArg' => [
'type' => 'String',
'description' => __( 'Description for how the argument will impact the field resolver', 'your-textdomain' ),
],
],
'resolve' => function( $source, $args, $context, $info ) {
if ( isset( $args['myArg'] ) ) {
return 'The value of myArg is: ' . $args['myArg'];
}
return 'test';
},
]);
});Bu örnek olabildiğince basit: resolver pratikte hiçbir şey yapmıyor. Yine de koda bakıp ne yaptığını bir anda anlamakta zorlanıyorum. Hayır, alaycılık yapmıyorum: editörümdeki tüm renkler dikkatimi çekiyor. Ayrıca sorumlulukların ayrıştırılması da yok; kod pek yeniden kullanılabilir görünmüyor.
Dolayısıyla, uygulamayı geliştirirken kodu okunabilir, yeniden kullanılabilir ve hatasız hâle getirmek geliştiriciye (yani size) kalıyor; kütüphanenin kendisi bu konuda pek yardımcı olmuyormuş gibi görünüyor.
Bu stile "ADD" (Array-Driven Development) diyorum. Hayranı olduğumu söyleyemem.
(WPGraphQL açısından adil olmak gerekirse, bu standart bir kodlama pratiği ve altta yatan motor olan webonyx/graphql-php tarafından da benimseniyor.)
Gato GraphQL'de tüm kod SOLID ilkelerine uyuyor. GraphQL şemasına bir alan kaydetmek için FieldResolverInterface arayüzünü uygulayan bir sınıf (aslında pek çok metodu zaten uygulanmış olan AbstractSchemaFieldResolver'ı genişleten) oluşturuyor ve container'a kaydediyoruz.
Örneğin şu kod, User tipine username, email ve url alanlarını sağlıyor:
class UserFieldResolver extends AbstractSchemaFieldResolver
{
public static function getClassesToAttachTo(): array
{
return [
UserTypeResolver::class,
];
}
public static function getFieldNamesToResolve(): array
{
return [
'username',
'email',
'url',
];
}
public function getSchemaFieldDescription(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
$descriptions = [
'username' => $this->translationAPI->__("User's username handle", "users"),
'email' => $this->translationAPI->__("User's email", "users"),
'url' => $this->translationAPI->__("URL of the user's profile in the website", "users"),
];
return $descriptions[$fieldName];
}
public function getSchemaFieldType(TypeResolverInterface $typeResolver, string $fieldName): ?string
{
$types = [
'username' => SchemaDefinition::TYPE_STRING,
'email' => SchemaDefinition::TYPE_EMAIL,
'url' => SchemaDefinition::TYPE_URL,
];
return $types[$fieldName];
}
public function resolveValue(TypeResolverInterface $typeResolver, object $user, string $fieldName, array $fieldArgs = [])
{
switch ($fieldName) {
case 'username':
return $this->usersAPI->getUserLogin($user);
case 'email':
return $this->usersAPI->getUserEmail($user);
case 'url':
return $this->usersAPI->getUserURL($user);
}
return null;
}
}Çözümümün WPGraphQL'inkinden daha zarif olduğuna inanıyorum. Ama bu bir zevk meselesi. Pek çok geliştiricinin Array-Driven Development'a itirazı olmadığını ve compakt bir kod bloğu içinde tüm mantığı uygulayabildikleri için bunu tercih ettiklerini biliyorum.
Round galibi: beraberlik.

Ara
Ne bir geceye sahip olduğumuzu, bayanlar ve baylar.

Dövüşün ortasına geldik; bu yüzden tuvalet molası ve şimdiye kadar yaşadıklarımızla ilgili yorum yapmak için iyi bir an.
(Bu arada sponsorlarımdan reklam göstermem gerekiyor. Maalesef henüz hiç sponsorum yok. Şirketinizin Gato GraphQL gelişimini desteklemesini ve bu etkinlik gibi birinci sınıf medyada yer almasını istiyorsanız bana mesaj gönderin.)

Ne bir maça sahip olduk! WPGraphQL başlangıçta tamamen ateş ve öfkeydi! Maça mükemmel girdi; Gato GraphQL'e iki ayaklarının üzerinde durmakta zorlandığı müthiş darbeler indirdi. Darbe üstüne darbe. Gato GraphQL'in yerinde olmak istemezdim.
İlk 2 rounddan sonra maçın yakında biteceğini düşündüğümü itiraf etmeliyim. Nakavtın her an gelebileceğini bekliyordum. Acıma dileyen sallanan bir havlu görmeyi. Ama Gato GraphQL direndi. Bunu ona teslim etmek gerekiyor. Ne sarsılmaz bir kararlılık, gerçekten dikkat çekici!
Ve sonra dönüşüm gerçekleşti. 3. roundun bir yerinden itibaren Gato GraphQL sanki enerjisini hiçlikten aldı; artık yalnızca savunmakla kalmıyor, pek çoğu WPGraphQL'in yüzüne isabet eden yumruklar geri atıyordu. WPGraphQL'in titrediğini ve sarsıldığını gördüm! Mevcut dünya şampiyonumuzdan böyle bir şey daha önce görülmemişti. Ne gerçekten dikkat çekici bir dönüşümü yaşadık az önce!
Ve sonra rakibinin özgüvenini sarsmış olan Gato GraphQL, 4. rounddan itibaren bir dizi ölümcül darbe indirmeye girişti. Bu şaşırtıcıydı! Neyse ki karşısında dünya şampiyonumuz WPGraphQL var; kitlelerin tezahüratları ve şefkatiyle yükselerek darbelere dayanmayı başardı. Ne bir kahraman! Başka biri anında yere serilirdi; ama o değil, şampiyon olduğu için bu darbelere katlandı.
Ama şampiyon, çok daha uzun süre şampiyon kalacak mı? Henüz kimse nakavt olmadı, henüz kimse havlu atmadı. Maç her an belirleyici bir dönüş alabilir. İki dövüşçü de ne istediklerini biliyor ve rakibine saldırmak, galip gelmek için tüm güçleri ve kararlılıklarıyla yeniden çıkacaklarından eminim.
Ne bir maça sahip olduk!
Ve şimdi, bayanlar ve baylar, iki savaşçı ringe geri dönüyor.

Maçın geri kalanına geçelim!
Acil meseleler
GraphQL sunucusunun "ihtiyacınız olan verileri alın, ne fazla ne eksik" önermesini karşılamak için bile pek çok konuya dikkat etmesi gerekiyor.
Örneğin:
- Ne kadar güvenli? Herkese açık bir endpoint'te özel verileri ifşa etmediğimizden nasıl emin oluruz?
- Ne kadar performanslı? Aynı sorguyu tekrar tekrar gönderirken sunucudaki yükü nasıl azaltır, aynı zamanda mümkün olduğunca hızlı hâle getiririz?
- Ne kadar basit? CMS'in sağladığı özelliklerden yararlanmak için WordPress ile ne kadar iyi entegre?
Ve daha pek çok soru. Bu, seçtiğim küçük bir örnektir; önümüzdeki 3 roundda bunları ele alacağım.
Round 7: Persisted queries
Persisted queries, GraphQL ve REST'in en iyisini bir arada sunar: GraphQL kullanılarak oluşturulurlar, dolayısıyla veri altında/üstünde çekme sorunu olmaz; ama kendi URL'sine sahip bir endpoint olarak sunucuda yayımlanırlar.
Persisted queries şu faydaları sağlar:
✅ Güvenli: tek endpoint aracılığıyla her veriye erişim vermek yerine hangi verilerin ifşa edileceğini önceden tanımlayabiliriz.
✅ Hızlı: kendi URL'si üzerinden erişildiği için istemci ile arka uç arasındaki her katmanda (sunucu, CDN, tarayıcı) standart HTTP caching kullanılarak önbelleğe alınabilir.
WPGraphQL, persisted queries desteğini şu iki eklenti aracılığıyla sunuyor:
Ayrıca WPGraphQL'in yaratıcısı Jason Bahl, yakın gelecekte WPGraphQL'e persisted queries desteği ekleyeceğini duyurdu.
2 eklenti zaten mevcut olduğu için ne düşündüğünü merak ediyorum. Bu eklentilerden nasıl farklı olacak? Belki üçüncü bir tarafa bağlı kalmadan genel eklenti güvenliğini güçlendirmek için onu eklentinin çekirdeğine dahil etmek istiyor?
Ya da belki Gato GraphQL'in uygulamasını gördü ve saf kod yerine görsel bir editör aracılığıyla işletilen benzer bir deneyim sunmak istiyor?
Ki bu bizi Gato GraphQL'e götürüyor. Yalnızca persisted queries sunmakla kalmıyor; onu teklifin merkezi bir parçası yapmaya çalışıyor:
✅ Eklenti tek endpoint'i devre dışı bırakmayı mümkün kılıyor ve kullanıcılar yalnızca persisted queries aracılığıyla veri ifşa etmeye teşvik ediliyor.
(Buna karşılık, WPGraphQL yalnızca varsayılan olarak introspection'ı devre dışı bırakıyor; endpoint'in kendisini değil. Başka bir deyişle saldırganlar yine de özel verilere erişebilir; yalnızca işleri zorlaştırılıyor çünkü önceden hangi özel verilerin olduğunu bilmeyecekler.)
✅ WordPress editörüyle derin biçimde entegre; persisted query oluşturmak bir blog yazısı oluşturmak kadar basit; yalnızca programcılar değil herkes yapabilir.
✅ Persisted queries statik değil: GraphQL değişkenleri kullanabilirler ve bu değişkenlerin değeri, endpoint çalıştırılırken URL parametreleri aracılığıyla sağlanabilir.
Eklentimdeki persisted query oluşturma ve çalıştırma deneyimine göz atın:
Round galibi: Gato GraphQL.
Round 8: Caching
GraphQL'in büyük bir sorunu var: kolayca önbelleğe alınamıyor. Bunun nedeni, tek bir endpoint'e POST işlemleri göndermeye dayanması. Tek endpoint farklı sonuçlar üreteceğinden ve sorgu, URL parametreleri yerine isteğin gövdesinde gönderildiğinden, tek endpoint önbelleğe alınamaz.
Pek çok GraphQL sunucusunun sunduğu standart çözüm, caching'i istemciye taşımak ve bir endpoint URL'si yerine önbelleğe alınacak varlığın tanımlayıcısı olarak nesnelerin ID'lerine güvenmektir. Bu işlevselliği sağlayan en popüler kütüphane Apollo client.
WPGraphQL için caching konusundaki tüm seçeneklerle ilgili WPGraphQL reposunda bir tartışma var. Ilginç biçimde bunların çoğu harici araçlar (Apollo client veya WordPress Object Cache gibi); bu da uygulamaya ekstra bir katman eklenmesi, karmaşıklığının artması ve muhtemelen daha yavaş hâle gelmesi anlamına geliyor.
(Bu nedenler, WPGraphQL'de persisted queries'in yerel olarak uygulanması kararının kısmen arkasında olmalı.)
Örneğin Apollo client, istemcide çalışıyor. Düşük kapasiteli bir cep telefonundan siteye erişildiğinde, o ekstra JavaScript kodu uygulamanın performansına olumsuz yansıyacak.
Benzer şekilde, WordPress ile çalışan geliştiriciler PHP'de yetkin olabilir ama JavaScript'te pek değil. Artık API'lerini önbelleğe almak JavaScript katmanıyla da ilgilenmek zorunda oldukları anlamına gelecek.
Gato GraphQL bu konuda daha akıllıca davrandı. Persisted queries sağladığı için; yani queries kendi endpoint'lerinde çalıştırıldığı için, bu endpoint URL'lerini HTTP caching aracılığıyla önbelleğe almayı mümkün kılıyor.
HTTP caching başlığının max-age değeri, sorguдaki tüm alanların tüm max-age değerlerinden otomatik olarak hesaplanıyor; bu bilgi ise WordPress editörü kullanılarak alan alan yapılandırılıyor.
Sonuç olarak API birden fazla katmanda (istemci, CDN ve sunucu) önbelleğe alınabiliyor; bu yerel olarak eklenti içinde yönetiliyor, başka bir katman eklenmesi gerekmiyor.
API endpoint'lerinin önbelleğe alınışını gösteren şu videoya göz atın:
Round galibi: Gato GraphQL.
Round 9: Gutenberg ile entegrasyon
Gutenberg, bir zamanlar WordPress'in geleceğiydi. Artık değil: Gutenberg bugün WordPress'in şimdisi (dolayısıyla WordPress editörü olarak anabiliriz) ve Full Site Editing yeni gelecek hâline geldi.
API'lerimizin WordPress editörüyle iyi bir entegrasyona sahip olması gerektiğini söylemeye gerek yok. Bu yalnızca bloklar için veri alıp göndermek değil, potansiyel olarak WordPress editörünün kendisindeki özellikleri de desteklemek anlamına geliyor.
Örneğin, GraphQL subscription'lar sunucunun gerçek zamanlı olarak istemciye veri göndermesine olanak tanıyabileceğinden, işbirlikçi düzenleme ve bildirimler özelliklerini desteklemek için uygun olurdu.
WPGraphQL, blok verilerini WPGraphQL Gutenberg eklentisi aracılığıyla sorgulayabiliyor. Bu eklenti her bloğu eşlemek için yeni bir tip oluşturuyor; böylece CoreParagraphBlock, CoreQuoteBlock vb. yapılar oluşuyor.
Gato GraphQL yakında blok verilerini sorgulayabilecek (hâlâ devam eden bir çalışma). Bununla birlikte, blok başına yeni bir tip oluşturmak yerine tüm blokları temsil etmek için tek bir Block tipi olacak; ardından bloğun adına göre belirli bir blok için özel meta verileri çıkarabileceğiz.
Örneğin, bir paragraf bloğunun içeriğini nasıl çevirebileceğinize bakın (@strTranslate direktifini kullanarak; bu direktif Google Translate API'sine bağlanıyor):
query TranslateStringsInBlocks {
post(by: { id: 1657 }) {
title
paragraphBlocks: blockDataItems(
filterBy: { include: "core/paragraph" }
)
translatedParagraphBlocks: blockDataItems(
filterBy: { include: "core/paragraph" }
)
@underJSONObjectProperty(by: { path: "attributes.content" })
@underEachArrayItem
@strTranslate(from: "en", to: "fr")
}
}Round galibi: beraberlik.
Kapsamı genişletmek
"Bir hayalim var."
Gutenberg blokları, WordPress'te içerik oluşturmak için tek bir arayüz sağlamak amacıyla tasarlandı; CMS için kod geliştirmeyi ve kullanıcıların öğrenmesi gerekenleri büyük ölçüde basitleştirdi.
İçerik oluşturmak için tanıtılmış olsalar da bloklar, widget'lar, menüler ve yakında Full Site Editing aracılığıyla temalar dahil CMS'in diğer tüm alanlarını giderek ele geçiriyor. Gelecekte çok dilli yetenekler ve işbirlikçi düzenlemeyi de destekleyecekler (bloklar düşünüldüğünde aklımıza bile gelmeyebilecek özellikler) ve kim bilir daha neler.
GraphQL'i de aynı terimlerle düşünebiliriz: verilerle etkileşim için tek bir arayüz. Bu, yalnızca veri alıp göndermek değil, düzenleme dahil veriyi içeren her türlü etkileşim anlamına geliyor.
WordPress'in gerçek anlamda webin işletim sistemi olma için eşsiz bir fırsatı var: Gutenberg tarafından desteklenen, kullanıcının her türlü içerik türünü (metin, görsel, video, ses vb.) girdiği, kendi araçları veya bulut tabanlı hizmetler aracılığıyla işlediği ve WordPress sitesine ya da başka bir yere nihai hedefine yayımladığı bir sistem.
Ama bu güçlü rüyanın arkasında gerçekten güçlü bir API olmak zorunda; üzerine koyduğumuz her gereksinimi karşılayan. GraphQL'e dayalı olabilecek ama sınırlarını da aşacak biçimde tasarlanmış bir API.
Round 10: Özel direktif desteği

WPGraphQL tek bir direktif ile gelmiyor. Bunları desteklemediğini söylemiyorum (altta yatan motor webonyx/graphql-php destekliyor); ama herhangi bir özel direktifin uygulamasını sunmuyor.
"Peki ne olmuş?" diye düşünüyor olabilirsiniz. "Direktiflere neden ihtiyacımız var? Biri sorgunun sonucunu değiştirmek istiyorsa bunu kendi istemcisinde yapabilir!"

Bu bir görüş meselesi ve doğru ya da yanlış yok. Ama şunu söyleyeyim: direktifler inanılmaz derecede yararlı bir özellik; GraphQL'i REST'ten ayırt etmeye yardımcı olan şeylerden biri. Kullanmıyorsanız büyük olasılıkla API'nızdan en iyi şekilde yararlanmıyorsunuzdur.
Direktifler spec tarafından düzenlenmemiş; dolayısıyla GraphQL sunucuları bunları istedikleri gibi uygulayabilir, ihtiyaç duydukları kadar güçlü yapabilir. Bu nedenle GraphQL'deki pek çok yeni işlevsellik ilk olarak direktifler aracılığıyla tanıtılıyor; @stream ve @defer gibi.
Gato GraphQL direktiflere saygıyla yaklaşıyor. Uygulandıkları tüm alanlar için tüm varlıkların verileriyle yalnızca bir kez çalıştırılıyorlar (bu, @strTranslate direktifinin Google Translate API'sinden sonuçları bu kadar hızlı alabilmesini açıklıyor) ve GraphQL motorunun kendisi bir direktif pipeline üzerine kurulu.
Ahhhh, ama tüm bu gücü kullanıcılara açmaktan korkuyorsunuz, değil mi? Geçerli bir endişe. Ama o zaman tek endpoint'e erişimi kaldırabilir ve verilere yalnızca persisted queries aracılığıyla erişim sağlayabilirsiniz; direktiflere erişim yalnızca sizenin (site yöneticisinin) elinde olur.
Dolayısıyla ya yararlanırsınız ya da hiçbir şey olmaz.
Direktifleri seviyorsanız harika, Gato GraphQL'i de seveceksiniz! ❤️
Öte yandan sevmiyorsanız da hiçbir şey olmaz.
Round galibi: Gato GraphQL.
(Eğer "pis direktiflere ihtiyacımız yok" diye düşünüyorsanız, lütfen bana kızgın olmayın... Ben sadece işimi yapıyorum.)
Round 11: REST desteği
"Ahhhhh? REST? Ne REST? Burada GraphQL'den mi konuşuyoruz? Neden REST'ten bahsediyorsun? Neden hayatımı zorlaştırmak istiyorsun?"

Evet, ilk bakışta bu konu yerinde değil gibi görünüyor. Ama çok basit bir nedenden ötürü bu karşılaştırmaya ekledim: Matt Mullenweg, GraphQL'i WordPress çekirdeğine potansiyel dahil edilme açısından değerlendirdiğini söyledi ve katkıda bulunanların endişeleneceği tek şey iki kod tabanını sürdürmek zorunda kalmak olacak.
Bu da bariz soruya götürüyor: GraphQL sunucusu REST'i de yönetebilir mi?
Yanıt WPGraphQL için "kısmen evet", Gato GraphQL için ise "tamamen evet".
WPGraphQL açısından: çözümlendiğinde gerekli alanları içeren bir GraphQL sorgusu çalıştıran REST endpoint tanımlamak mümkün; ya GraphQL motoruna dahili bir çağrı olarak ya da aynı web sunucusuna karşı gerçekleştirilen harici bir POST işlemi olarak. Ama bu WP REST API'yi tatmin etmeye yetmiyor çünkü onun da bir JSON şeması var ve onsuz olmaz.
Gato GraphQL açısından: şanslı olduğumu itiraf etmeliyim çünkü altta yatan motorunun (PoP adlı sunucu taraflı bileşen modeli) üzerindeki çalışmalar, GraphQL diye bir şey duyduğumdan birkaç yıl önce, yaklaşık 2013 yılında başladı; bu proje kendi fikirleriyle evrildi (bunları bu vintage makalemde belgeledim).
Sonra, yaklaşık 1,5 yıl önce CMS-agnostik GraphQL sunucusunu (Gato GraphQL'in üzerine inşa edildiği) kodlamaya başladığımda, PoP için geliştirilen fikirleri GraphQL'in kurduğu temellerle birleştirdim; böylece GraphQL spesifikasyonunu bütünüyle desteklerken farklı bir özellik seti de ekleyebilen bir sistem yarattım.
Bu bağlamda PoP'un kullandığı şema API-agnostik ve GraphQL'inkinin bir üst kümesi. PoP şeması /api/graphql/?query=fullSchema altında bulunuyor.
Ardından GraphQL sunucu katmanı, PoP şemasını GraphQL spesifikasyonunu izleyerek biçimlendiriyor; bu da GraphQL şemasını üretiyor. Benzer şekilde, WP REST API'nin gerektirdiği JSON şemasını da üretebiliriz.
Bu JSON şemasının oluşturulması henüz yapılmadı; ama yapılabilir.
Şimdiye kadar yapılmış olan şey ise sorgunun yanıtını birden fazla formatta üretmek. Örneğin şu GraphQL sorgusu:
{
posts {
id
title
date
author {
name
}
}
}Şu REST endpoint'i aracılığıyla da çözümleniyor: /posts/api/rest/?query=id|title|date|author.name.
Burada durmamıza gerek yok. Sonuçları XML gibi farklı bir formatta üretmeniz mi gerekiyor? Sorun değil: /api/?query=posts.id|title|date|author.name&datastructure=xml.
(Bu, şema tabanlı WordPress için yeni bir içe/dışa aktarma aracı önerisinin uygulanmasına yardımcı olabilir. Bu aynı zamanda daha önce söylediğimi biraz daha netleştiriyor: tek bir arayüz hem CMS içindeki hem de CMS ile harici API'ler arasındaki tüm veri etkileşimlerini yönetebilir.)
Round galibi: Gato GraphQL.
Round 12: Yeni özellikler için destek
GraphQL spesifikasyonu nihai mi? Yanıt hayır: spec sürekli gelişiyor. Şu anda 100 açık issue var ve bunların pek çoğu gelecekte bir noktada resmileştirilecek öneriler içeriyor.
Şimdi, bu 100 issue arasında bugün yararlana bileceğimiz yeni özellikler kesinlikle vardır, değil mi? Eğer öyleyse neden bekleyelim?
Tam olarak benim düşünce biçimim bu.

"Ama bir şey GraphQL spec'inde değilse, GraphQL sunucusuna eklemeliyiz; aksi takdirde kullanıcılar kafaları karışır!"
Güzel bir nokta. Bununla birlikte, yeni özellikleri yalnızca opt-in olarak kullanılabilir kılarsak kullanıcılar bunun farkında olmak zorunda olacak ve hiçbir sorun ya da yanlış anlama yaşanmayacak.
Yine de bu benim düşünce biçimim. Bir görüş meselesi; dolayısıyla yalnızca diğer GraphQL sunucularının da kullandığı özellikleri kullanmayı tercih ediyorsanız sorun değil.
WPGraphQL'in bu şekilde çalıştığını düşünüyorum. En azından spec'te onaylanmış olanın ötesine geçen tek bir özellik görmedim.
Gato GraphQL için ise spec'teki issue listesini düzenli olarak tarıyorum; eğer sunucum tarafından çok fazla çaba gerektirmeden karşılanabilen harika bir özellik bulursam uyguluyorum. (Aslında bu hobilerimden biri.)
Bugüne kadar uyguladığım "geleceğe yönelik" özellikler şunlar:
✅ Çoklu sorgu çalıştırma
✅ Şema adlandırma alanı
✅ İç içe mutation'lar
✅ Bileşen direktifler
✅ Proaktif geri bildirim
✅ Alan ve direktif tabanlı sürümleme
Ve eklemeyi zaten planlıyorum:
✳️ Subscription'lar (bu zaten spec'in parçası)
✳️ @stream ve @defer direktifleri
✳️ Düz zincir sözdizimi
Round galibi: Gato GraphQL.
Karar!
Bayanlar, baylar.

Ne unutulmaz bir gece geçirdik! Ne bir maça tanıklık ettik! İki ağır siklet, hayalleri için ellerinden gelenin en iyisini verdi.
Her ikisinin de peşinde koştuğu ama yalnızca birinin yakalayabileceği bir hayal.
Ve şimdi o kişinin kim olduğunu öğreneceğiz. Şimdi gerçeğin zamanı!
"WordPress'te GraphQL" dünya şampiyonu kim olacak?
Geniş kitlelerce övülen, büyük yayın organlarında yer bulan mevcut şampiyon WPGraphQL mı?
Yoksa saygısız, af dilemeden ayağınıza basan, davete çağrılmadan gelen meydan okuyucu Gato GraphQL mi?

Yargıcın kararını bekliyoruz. Ne gerilim! Ah Santa Maria, kalbimin bu ana dayanmasını sağla!
🥁 Ve 🥁 galip 🥁 gelennnnnnnnnnn 🥁 ...
Beraberlik!
2 dövüşçü, 2 ağır siklet, berabere!

Ne harika bir an! İki rakip birbirini kucaklıyor; WordPress topluluğu içinde hepimizin, büyük bir aile gibi, dost olduğunu gösteriyor.
Peki beraberliğin gerekçesi ne? Yargıç açıklıyor:
👑 WPGraphQL daha popüler ve kullanımı daha yaygın.
👑 Gato GraphQL daha iyi bir mimariye sahip ve uzun vadede WordPress'e daha iyi hizmet edebilir.
Bayanlar ve baylar, yargıcın kararını duydunuz!
Ve kupamızın iki eldiveni var: her rakip için birer tane.

Peki sizin kararınız nedir?
Headless ihtiyaçlarınız için WPGraphQL'i koşulsuzca kullanmaya devam mı edeceksiniz?
Yoksa Gato GraphQL'e talep ettiği fırsatı verecek misiniz; eklentiyi indirin ve bir deneyin mi?
Bayanlar ve baylar. Bu gece için bu kadar.
Maçın tadını çıkardığınızı umuyoruz.
Ve iki şampiyonumuz arasında yakında yeni bir karşılaşma diliyoruz.
İyi geceler.
Güncelleme 01/05/2024: Gato GraphQL vs WPGraphQL karşılaştırmasında daha fazlasını öğrenin.