Bir GraphQL Video Keşif API'si Oluşturmak

Video veritabanımız yüz binlerce kayda ulaştığında, API'miz darboğaz haline geldi.

Tek bir ekranın trend videoları, kanal detaylarını, etiketleri, izlenme sayılarını ve önerileri göstermek için beş farklı REST çağrısına ihtiyacı vardı. Yavaş bağlantıya sahip mobil kullanıcılar, tek bir sayfayı yüklemek için 30 istek göndermek zorunda kalıyordu.

GraphQL bunu çözer. İstemci, tek bir istekte tam olarak ihtiyacı olanı ister.

Strawberry ve FastAPI kullanarak üretim ortamına hazır (production) bir video keşif API'si inşa ettim. İşte bunu nasıl yaptığım.

Neden Strawberry?

Graphene ve Ariadne'yi test ettim ancak Strawberry şu nedenlerle kazandı:

• Tip ipuçları (type hints) şemadır. Python kodu yazarsınız ve Strawberry GraphQL tiplerini oluşturur. Manuel senkronizasyona gerek kalmaz. • Async-native bir yapısı vardır. Bu, API'nin olay döngüsünü (event loop) engellemeden birçok isteği işlemesine olanak tanır. • FastAPI entegrasyonu kusursuzdur. GraphQL uç noktası (endpoint), mevcut REST rotalarının hemen yanında yer alır. • Yerleşik DataLoader. Bu araç, N+1 problemini doğrudan çözer.

Veri Yığını (The Data Stack)

Veriler, bir PHP sitesi tarafından yönetilen bir SQLite veritabanında duruyor. Hızlı tam metin araması için SQLite FTS5 kullanıyorum.

Python servisi bu veritabanını salt okunur (read-only) bir katman olarak okur. Bu, tek bir doğruluk kaynağı (source of truth) olmasını sağlar.

Aramanın iyi hissettirmesi için FTS5 alaka düzeyi puanlarını bir popülerlik sinyaliyle harmanlıyorum. Bu, tek bir viral videonun diğer tüm arama sonuçlarını gölgede bırakmasını engeller.

N+1 Problemini Çözmek

GraphQL'deki yaygın bir tuzak N+1 problemidir. Eğer 20 video çekip ardından her biri için kanalı çekerseniz, basit bir API 21 veritabanı sorgusu çalıştıracaktır.

DataLoader, gruplandırma (batching) yaparak bunu düzeltir. Tüm kanal kimliklerini (ID) tek bir döngüde toplar ve hepsini getirmek için tek bir sorgu çalıştırır. Bu, sorgu süremizi 40ms'den 5ms'nin altına düşürdü.

Temel Tasarım Seçimleri

• Opak (Opaque) ID'ler: ID'ler için dize (string) kullanıyorum. Bu, istemci uygulamalarını bozmadan gelecekteki değişikliklere olanak tanır. • Kasıtlı Nullability: Hangi alanların boş olabileceğini tanımlıyorum. Bu, istemcilerin çökmeden eksik verileri işlemesine yardımcı olur. • Salt Okunur Şema: GraphQL API yazma işlemlerini gerçekleştirmez. Bu, birçok güvenlik sorununu ortadan kaldırır. • Kenar Önbelleğe Alma (Edge Caching): GraphQL varsayılan olarak POST kullanır, bu da önbelleğe alınmasını zorlaştırır. Cloudflare üzerinden önbelleğe almaya izin vermek için Automatic Persisted Queries (APQ) kullanıyorum.

Çok fazla özel uç nokta veya karmaşık sorgu parametreleriyle sorun yaşıyorsanız, bu yığın güçlü bir seçenektir.

Kaynak: https://dev.to/ahmet_gedik778845/building-a-graphql-video-discovery-api-with-strawberry-and-fastapi-1dp2