Öncelikle, her mobil istemci versiyonunun hangi özel alanları kullandığını belgeleyerek sistematik bir sürüm-matris metodolojisi oluşturun. Bunu gerçekleştirmek için Charles Proxy veya Burp Suite kullanarak üretim trafiğini yakalayarak, iOS ve Android uygulama sürümleri ile GraphQL şema alanlarını ilişkilendiren bir bağımlılık haritası oluşturun. Eski istemci isteklerini taklit eden manuel sorgular oluşturarak sözleşme doğrulamalı keşif testleri gerçekleştirin ve kaldırılmış alanlara kasıtlı olarak null değerler ekleyerek mobil istemcilerin eksik verileri hata sınırlamaları aracılığıyla ele alıp almadığını kontrol edin. Postman koleksiyonları aracılığıyla eşzamanlı REST ve GraphQL istekleri çalıştırarak gölge testleri uygulayın, yanıt yüklerini anlamsal eşdeğerlik açısından karşılaştırarak, kaldırılma başlıklarının ve @deprecated direktiflerinin kullanıcı arayüzünü bozmadığını kontrol edin.
Problemin Tanımı
E-ticaret platformumuz, ürün kataloğunu yeni bir öneri motorunu desteklemek için REST uç noktalarından birleşik bir GraphQL şemasına geçiş yapıyordu, ancak iOS'un 12.4 (2019'da yayınlandı) sürümüne kadar ve Android'in API 28 (Android 9) seviyesine kadar olan sürümlerini destekliyorduk, bu da daha farklı GraphQL istemci yeteneklerine sahip 15'ten fazla aktif uygulama sürümünün bir matrisini oluşturuyordu. Kritik risk, iOS v14.2 istemcilerinin productVariants kaldırılmış alanına bağımlı olmasıydı; bu alan productOptions ile değiştirilecekti ve bu alan beklenmedik null değerleri döndürdüğünde, Swift ayrıştırma mantığı uygulamayı zorla çökertiyordu. Dahası, Android istemcileri Apollo Client v2.5 kullanarak null değerleri farklı bir şekilde ele alıyordu; bu da aynı şema değişikliğinin bir platformda sessiz veri bozulmasına, diğerinde ise çökmesine neden olabileceği anlamına geliyordu.
Çözüm 1: Kapsamlı uçtan uca regresyon testi
Desteklenen her işletim sistemi sürümü için fiziksel cihazlarda tam regresyon testleri yürütmeyi düşündük, ürün kataloğu akışlarında manuel olarak gezinti yaparak tüm platformlarda görsel tutarlılığı ve veri bütünlüğünü doğruladık. Bu yaklaşım, kullanıcıya açık işlevselliğin doğru çalıştığından kesin bir güvence sağlayacak ve GraphQL veri bağlama ile ilgili platforma özgü kullanıcı arayüzü hatalarını yakalayacaktı. Ancak, bu, 40'tan fazla fiziksel cihaza erişim ve yaklaşık üç haftalık test süresi gerektiriyordu, bu da iki haftalık göç sürelimizi aşıyor ve yalnızca belirli ağ koşullarında ortaya çıkan ince API sözleşmesi ihlallerinin tespit edilmesini garanti etmiyordu.
Çözüm 2: Sahte istemci yanıtlarıyla API sözleşmesi testi
İkinci yaklaşım, Postman ve Mockoon kullanarak eski mobil istemciler tarafından gönderilen tam sorgu yapılarını simüle etmek, GraphQL şemasının tarihsel REST yük yapılarıyla eşleşen sözdizimsel olarak doğru JSON yanıtları döndürdüğünü doğrulamak için kullandık. Bu yöntem önemli ölçüde daha hızlıydı, tüm sürüm kombinasyonlarını üç gün içinde test etmemize olanak tanıdı ve kaldırılma başlıkları ile alan nullabilitesinin kesin doğrulamasını sağladı. Ne yazık ki, bu tamamen sentetik test, yalnızca gerçek istemci ortamlarında meydana gelen beklenmeyen null değerler ile eksik anahtarların iOS Swift Codable protokolü üzerinde başarısız olduğu gibi kritik platforma özgü ayrıştırma davranışlarını kaçırdı.
Çözüm 3: Üretim analizleri ile risk tabanlı kesme testi
Sonunda, %85'lik aktif kullanıcı tabanımızı temsil eden her platform için en üst üç işletim sistemi sürümünü belirlemek üzere Firebase Analytics verilerini analiz eden hibrit bir stratejiyi seçtik. Ardından, canlı trafiği yakalayıp REST yanıtlarını GraphQL sorgularına yeniden yazmak için Charles Proxy kullandık ve istemci istikrarını izledik. Bu, gerçek dünya sorgu kalıplarını ve ağ gecikmesi koşullarını test etmemizi sağlarken, manuel doğrulama çabalarımızı yüksek etkili sürüm kombinasyonlarına odaklanarak, uç durumlar için otomatik sözleşme testleriyle destekledik. Bunun, zaman kısıtlamalarıyla risk kapsamını dengelemesi ve çoğu kullanıcının göçten etkilenmeyeceğinden emin olmamızı sağlaması nedeniyle tercih ettik; iOS null işleme hatası gibi belirli uyumluluk sorunlarını tanımladık.
Seçilen çözüm ve sonuç
Çözüm 3'ü uyguladık, manuel testimizi iOS 14.2, 15.0 ve 16.0 ile Android 10, 11 ve 12'ye odakladık, Charles Proxy kullanarak productVariants alanının kaldırılmasını simüle etmek amacıyla null değerler döndürdük ve çökme durumlarını izledik. iOS v14.2'nin testinde, kaldırılmış alan null döndüğünde, istemci uygulamanın bir EXC_BAD_ACCESS hatası ile çöktüğünü keşfettik; bu da alternatif UI gösterimi yerine GraphQL hata yanıtını yanlış bir şekilde ayrıştırdığını ortaya koydu. Bunu kritik bir defekt olarak belgeledik, sunucu tarafında null değerler yerine boş dizilerin kaldırılma uyarılarıyla döndürülmesi için bir şema değişikliği gerçekleştirdik ve uygulama sürümüne göre GraphQL hata oranları için izleme uyarıları kurduk; göç, desteklenen sürümlerde sıfır çökme ile gerçekleşti.
Manuel testlerde GraphQL sorgu derinliği sınırlarının ve karmaşıklık puanlamasının düzgün bir şekilde uygulanıp uygulanmadığını sunucu tarafı günlüklerine veya otomatik yük test araçlarına erişim olmadan nasıl doğruluyorsunuz?
Birçok aday, GraphQL güvenliğini test etmenin otomatik betikler gerektirdiğini varsayıyor. Ancak, manuel testçiler, GraphiQL veya Insomnia kullanarak döngüsel referanslar veya derin nesne yapıları oluşturarak DoS koruma mekanizmalarını tetikleyebilirler. API'nin belirli hata kodları döndürdüğünü doğrulamalısınız; örneğin GRAPHQL_VALIDATION_FAILED veya QUERY_TOO_COMPLEX gibi, genel 500 hataları yerine hata iletimlerini doğrulamalısınız. Ayrıca, karmaşıklık hesaplamalarının, bir istekte farklı isimlerle aynı alanı talep ederken alan kat sayılarını doğru bir şekilde dikkate aldığını test edin. Bu manuel doğrulama, sunucunun karmaşıklık analizinin istenen alanları doğru bir şekilde saymasını ve yapılandırılmış eşikleri aşan sorguları veritabanı kaynaklarını tüketmeden reddetmesini sağlar.
Ayrıca, adaylar genellikle korunmuş sorguların (izin verilen sorgu beyaz listesinin) üretim ortamlarında keyfi manuel sorguları reddettiğini test etmeyi unutur; bu, kaynak tükenmesi saldırılarını önlemek için kritik öneme sahiptir. Bunu doğrulamak için, Postman üzerinden korunmuş sorgu karmaşasından sapan ad-hoc sorgular çalıştırarak sunucunun PersistedQueryNotFound hatası veya eşdeğerini döndürdüğünden emin olun; bu da sorgunun çalıştırılmasını engeller. Bu güvenlik sınırı, saldırganların meşru kullanıcıların sistem performansını düşüren kaynak yoğun sorgular oluşturmasını önler.
Birden fazla mikro hizmetin aynı varlık türüne alanlar sağladığı GraphQL şema dikmesi veya federasyon testi için sistematik yaklaşım nedir; özellikle bir hizmet bozulduğunda hata iletimi açısından?
Apollo Federation veya şema dikme mimarilerinde, acemiler genellikle her hizmeti izole bir şekilde test eder ve Kullanıcı türünün Kimlik Doğrulama Servisi (kritik) ve Tercihler Servisi (önemli olmayan) alanlarını birleştirdiği kısmi hataları test etmeyi kaçırır. Akışına engel olmak için belirli uç noktaları bloke ederek ya da Chaos Monkey tekniklerini kullanarak, aşağı akışta hizmetlerde hatalar tetiklemelisiniz; ardından Gateway'in null alanlarla kısmi veriler döndürdüğünü ve hataların errors dizisinde belirli hata yollarıyla döndüğünü doğrulayın; böylece tüm sorgunun başarısız olmaması ve tamamen sayfa çökmesine neden olmaması sağlanır. Bu yaklaşım, federasyon katmanının dayanıklılığını doğrulamakta ve kritik kullanıcı yolculuklarının, önemsiz hizmetler kesintiye uğradığında bile işlevsel kalmasını sağlamaktadır.
Temel bilgi, @defer ve @stream direktiflerinin, tüm UI'yi engellemeden yavaş yanıt veren alanları uygun şekilde ele almasını ve istemcinin belirli bileşenler için alternatif içerik görüntülemek üzere kullanılabilir verileri sunarken yanlış bilgiler iletmemesini doğrulamaktır. Test uzmanları, GraphQL yanıtının extensions kısmının hangi belirli mikro hizmetin başarısız olduğunu gösteren doğru hizmet izleme bilgilerini içermesini kontrol etmelidir ki bu, frontend'in bozulmuş durumda neleri gizleyip neleri göstereceği konusunda akıllıca kararlar vermesini sağlar. Uygun hata iletimi testi, kullanıcıların tamamlayıcı özellikler gibi öneriler veya analizler geçici olarak kullanılamadığında bile temel işlemleri tamamlayabilmelerini sağlar.
Kod üretim araçları gibi Apollo Codegen veya GraphQL Codegen kullanan uygulamalarda tasarlanan GraphQL nullabilitesini (meşru olarak null olabilen alanlar) ve gerçek defektler arasında nasıl ayırt edersiniz?
Adaylar sıklıkla iş mantığının gerektirdiği alanların seçimli (null olabilen) olarak işaretlendiği durumlarla karşılaşacak ve bir null değerinin bir hata mı yoksa geçerli bir boş durum mu temsil ettiğine dair kafa karışıklığına neden olacaktır. Şemanın ünlem işaretlerine (!) ve üretilen istemci türlerine bakarak sınır koşullarını test etmelisiniz; ayrıca Charles Proxy üzerinde JSON yanıtlarını manuel olarak değiştirerek, null değerleri null olmayan şema alanlarına enjekte ederek sunucunun, istemciye yanıt göndermeden önce verileri düzgün bir şekilde doğruladığını kontrol etmelisiniz. Bu ayrım kritik öneme sahiptir çünkü bir null değerinin null olmayan bir şema alanında sunucu tarafında bir defekti gösterirken, bir null değeri null olduğu belirtilen bir alanda veri eksikliği olarak meşru bir durumu temsil edebilir.
Ayrıca, istemci uygulamasının şema kaynaklı nullabiliteyi düzgün bir şekilde ele aldığını doğrulamalısınız, bu da potansiyel null alanlara erişim sağlarken TypeScript sıkı modu derlemesinin başarılı olmasını sağlamak anlamına gelir; böylece üretilen türlerin yalnızca şemayı yüzeysel olarak eşleştirmediğinden değil, aynı zamanda çalışma zamanı null işaretçisi hatalarına karşı da koruma sağladığından emin olursunuz. Bu, GraphQL null olamaz alanlarının sunucudan kesinlikle null döndürmemesi ve null alanların istemci kodunda her zaman seçilmeli veya null kontrolü yapılmalı olduğunu anlamayı gerektirir; iş mantığı verilerin her zaman mevcut olduğu varsayımlarına rağmen. Geliştiriciler, iş mantığı verilerin her zaman var olduğunu öngördüğünde, bu savunucu kontrolleri eklemeyi sıkça unutur; bu nedenle null enjeksiyonu ile titiz manuel test, potansiyel çöküşleri üretim kullanıcılarına ulaşmadan yakalamaya yardımcı olur.