Kaynaklar
KaynaklarGraphQL en iyi uygulamalar

GraphQL en iyi uygulamalar

GraphQL yeterince olgunlaşmış ve yeterince uzun süredir hayatımızda yer almış olup topluluk tarafından en iyi uygulamaları paylaşan pek çok makale yayımlanmıştır. Bu rehberler; şema tasarımı, adlandırma kuralları, güvenlik yönetimi ve anlamlı hatalar sağlama gibi konular dahil olmak üzere GraphQL'in hemen hemen tüm yönlerini kapsamaktadır.

Bunlar, GraphQL'deki en iyi uygulamalar hakkında mevcut en ilgi çekici rehberlerden bazılarıdır.

graphql.org üzerindeki en iyi uygulamalar

Resmi GraphQL sitesi, GraphQL'deki en iyi uygulamalara genel bir giriş sunmaktadır.

Bu maddeler ağırlıklı olarak üst düzey konuları kapsamaktadır; örneğin:

GraphQL katmanının mimari içindeki konumu

Lee Byron'ın tavsiyeleri

GraphQL'i dünyaya tanıtmasından kısa bir süre sonra, GraphQL'in yaratıcısı Lee Byron, Lessons From 4 Years of GraphQL adlı makalesini yayımladı; bu makalede GraphQL ile kavramsal olarak nasıl çalışmamız gerektiğini açıkladı:

  • İsimlendirme önemlidir
  • Endpoint'ler değil, grafikler üzerinden düşünün
  • Görünümü değil, veriyi tanımlayın
  • GraphQL ince bir arayüzdür
  • Uygulama ayrıntılarını gizleyin

Ayrıca Facebook'ta GraphQL kullanırken öğrendiği değerli birkaç ilkeyi ve dersi de ayrıntılı biçimde aktarmaktadır.

GraphQL Rules

GraphQL Rules, GraphQL ile çalışmaya yönelik günlük en iyi uygulamaları sunan ve ağırlıklı olarak GraphQL şema tasarımıyla ilgilenen özel bir sitedir.

Bu kaynak oldukça kapsamlıdır. Designing GraphQL Mutations makalesi ve Shopify'ın Designing a GraphQL API eğitimi gibi birkaç istisnai kaynaktan derlenen bilgileri bir arada ve özlü bir biçimde sunmaktadır.

Açıklanan kurallar şunları içermektedir:

  1. Adlandırma kuralları
    • GraphQL alan ve argümanları için camelCase kullanın.
    • GraphQL türleri için UpperCamelCase kullanın.
    • ENUM türlerini adlandırmak için CAPITALIZED_WITH_UNDERSCORES kullanın.
  2. Tür kuralları
    • Belirli semantik değere sahip alan veya argümanlar tanımlamak istiyorsanız özel scalar türleri kullanın.
    • Belirli bir değer kümesi içeren alanlar için Enum kullanın.
  3. Alan kuralları (Çıktı)
    • Alanlar için anlamlı isimler kullanın ve alan adlarında uygulama ayrıntılarının sızmasından kaçının.
    • Bir alan her zaman belirli bir değere sahip olacaksa Non-Null alanı kullanın.
    • Birbiriyle ilgili mümkün olduğunca fazla alanı özel bir Object türü içinde gruplayın.
  4. Argüman kuralları (Girdi)
    • Birbirine bağlı argümanları yeni bir input türünde gruplayın.
    • Argümanlar için String yerine DateTime gibi katı scalar türler kullanın.
    • Query çalıştırması için zorunlu olan argümanları required olarak işaretleyin.
  5. Liste kuralları
    • Listeleri filtrelemek için mevcut tüm filtreleri içeren filter argümanını kullanın.
    • Liste sıralamak için Enum veya [Enum!] türünde sort argümanı kullanın.
    • Listede döndürülen öğe sayısını sınırlamak için varsayılan değerli limit ve skip kullanın.
    • Sayfalama için page, perPage argümanlarını kullanın ve items (öğe dizisi) ile pageInfo (meta veri) içeren bir çıktı türü döndürün.
    • Sonsuz listeler (sonsuz kaydırma) için Relay Cursor Connections Specification kullanın.
  6. Mutation kuralları
    • Mutation'ları tek bir kaynak içinde gruplamak için Namespace türlerini kullanın.
    • CRUD'un ötesine geçin – kaynaklar üzerindeki farklı iş operasyonları için küçük mutation'lar oluşturun.
    • Birden fazla öğe üzerinde mutation gerçekleştirme imkânını göz önünde bulundurun (aynı türde toplu değişiklikler).
    • Mutation'lar tüm zorunlu argümanları açıkça belirtmeli; ya-ya seçenekleri bulunmamalıdır.
    • Mutation'larda tüm değişkenleri tek bir benzersiz input argümanına koyun.
    • Her mutation'ın benzersiz bir payload türü olmalıdır.

Resolver en iyi uygulamaları

GraphQL Resolvers: Best Practices makalesi, alan resolver'larını en iyi şekilde nasıl oluşturacağınızı açıklamaktadır. Node.js sunucularına (PayPal'ın altyapısı Express tabanlıdır) yönelik olsa da derslerinin birçoğu PHP dahil diğer teknolojiler için de uygulanabilir.

Temel çıkarımlar şunlardır:

  • Üstten alta veri çekme ve iletme işlemi tutumlu kullanılmalıdır.
  • Alt akış isteklerini tekilleştirmek için dataloader gibi kütüphaneler kullanın.
  • Veri kaynaklarınız üzerinde yarattığınız baskının farkında olun.
  • "context"i mutasyona uğratmayın. Bu, tutarlı ve daha az hatalı kod sağlar.
  • Okunabilir, sürdürülebilir ve test edilebilir resolver'lar yazın. Fazla karmaşık olmayan.
  • Resolver'larınızı mümkün olduğunca sade tutun. Veri çekme mantığını yeniden kullanılabilir async fonksiyonlara çıkarın.

OWASP - GraphQL Kopya Kağıdı

OWASP (Open Web Application Security Project), yazılımın güvenliğini artırmak için çalışan kar amacı gütmeyen bir kuruluştur. Farklı teknolojilerin açıklara karşı nasıl savunmasız olduğunu araştırır ve güvenlik sorunlarına çözümler ayrıntılı biçimde tanımlar; bu sayede geliştiricilerin saldırıları önlemesi kolaylaşır.

OWASP, GraphQL Cheat Sheet'i yayımlamıştır; bu belge GraphQL'deki en yaygın saldırıları ve en büyük güvenlik sorunlarını açıklamakta ve bunların nasıl ele alınacağını anlatmaktadır.

GraphQL'e yönelik yaygın saldırılar şunlardır:

  1. Injection - bu genellikle şunları içerir ancak bunlarla sınırlı değildir:
    • SQL ve NoSQL injection
    • OS komut injection
    • SSRF ve CRLF injection / Request Smuggling
  2. DoS (Hizmet Reddi)
  3. Bozuk yetkilendirmenin kötüye kullanımı: IDOR dahil uygunsuz veya aşırı erişim
  4. Batching Attacks, GraphQL'e özgü bir kaba kuvvet saldırısı yöntemi
  5. Güvensiz varsayılan yapılandırmaların kötüye kullanımı

OWASP daha sonra bunların her birinden nasıl kaçınılacağına dair öneriler sunmaktadır.

GraphQL queries ile en iyi uygulamalar

Apollo ekibi, GraphQL query oluşturmanın pratik yollarına ilişkin pratik içgörüler sunan GraphQL query best practices rehberini yayımlamıştır.

Örneğin, bu iki queries aynı amaca ulaşmaktadır; ancak ilkinin bir operasyon adı olduğu için hata ayıklama sırasında daha anlaşılır ve yararlıdır:

# Önerilen ✅
query GetBooks {
  books {
    title
  }
}
 
# Önerilmeyen ❌
query {
  books {
    title
  }
}

Önerileri şunları içermektedir:

  • Tüm operasyonları adlandırın
  • GraphQL argümanlarını sağlamak için değişkenler kullanın
  • Yalnızca ihtiyaç duyduğunuz veriyi, ihtiyaç duyduğunuz yerde sorgulayın
  • İlgili alan kümelerini kapsüllemek için fragment'lar kullanın
  • Global veriyi ve kullanıcıya özgü veriyi ayrı ayrı sorgulayın

Tek grafı kullanmak

Yine Apollo ekibinden Principled GraphQL sitesi, GraphQL'in yalnızca bir spesifikasyon olmadığını; belki daha da önemlisi, şirketimizdeki veri "grafı" ile etkileşim kurmak için bir arayüz olduğunu açıklamaktadır.

10 ilkenin yer aldığı bir liste aracılığıyla bu site, tek graftan en iyi şekilde nasıl yararlanılacağını açıklamaktadır:

  1. One Graph: Şirketinizin, her ekip tarafından oluşturulan birden fazla graf yerine tek bir birleşik grafa sahip olması gerekir.
  2. Federated Implementation: Tek bir graf olmasına rağmen, o grafın uygulanması birden fazla ekip arasında federe edilmelidir.
  3. Track the Schema in a Registry: Grafı kaydetmek ve takip etmek için tek bir doğruluk kaynağı olmalıdır.
  4. Abstract, Demand-Oriented Schema: Şema, tüketicilere esneklik sağlarken hizmet uygulama ayrıntılarını gizleyen bir soyutlama katmanı işlevi görmelidir.
  5. Use an Agile Approach to Schema Development: Şema, gerçek gereksinimlere dayalı olarak artımlı biçimde oluşturulmalı ve zaman içinde sorunsuz bir şekilde evrilmelidir.
  6. Iteratively Improve Performance: Performans yönetimi, değişen query yüklerine ve hizmet uygulamalarına sorunsuzca uyum sağlayan sürekli, veri odaklı bir süreç olmalıdır.
  7. Use Graph Metadata to Empower Developers: Geliştiriciler, tüm geliştirme süreci boyunca graf hakkında zengin bir farkındalıkla donatılmalıdır.
  8. Access and Demand Control: Grafa her istemci bazında erişim tanıyın ve istemcilerin neye nasıl erişebileceğini yönetin.
  9. Structured Logging: Tüm graf operasyonlarının yapılandırılmış günlüklerini tutun ve bunları graf kullanımını anlamak için birincil araç olarak kullanın.
  10. Separate the GraphQL Layer from the Service Layer: Her hizmete entegre edilmek yerine graf işlevselliğinin ayrı bir katmana bölündüğü katmanlı bir mimari benimseyin.