💻
Gürkan Fikret Günak - Personal
  • 👨‍💻About me
    • 🌊Journey
  • 🎯Dart
    • 🔬What's Dart Algorithms?
    • 🔬What's Dart Structures?
    • 🧮#01 Algorithm Guidance: Implementing Calculation Algorithms
    • 🧮#02 Algorithm Guidance: Two Sum
  • 📄Guidances
    • Flutter MVVM Guidance
    • Dart Programming Guidance
    • E-Commerce Use Cases
    • E-Commerce Applications
    • Flutter App Color Palette Usage Guidance
    • Flutter Custom AppBar Usage Guidance
    • Flutter Network Image Cache Usage Guidance
    • Flutter Project Bitbucket SSH Guidance
    • Flutter Project GitHub SSH Guidance
    • Flutter SliverAppBar Usage Guidance
    • The Importance of BuildContext in Flutter Tests Guidance
    • Internship Basic Guidance v0.1.0
    • The Importance of Type Casting in Flutter
    • Effective and Detailed Pull Request Guide
    • Flutter Naming Conventions Guidance
    • Flutter Widget Guidance
    • Semantic Commit Guidance
    • Being Part of a Mobile Software Team and Working on a Shared Architecture
    • Understanding Deep Links for Any Development Platform
    • The Journey of a Developer: Stories of Becoming Junior, Middle, and Senior Developer
    • Becoming a Team Leader: Growing in Sync with Your Team
    • Why IP Changes Are Important for Mobile Applications in Flutter
    • Why Your Growing Mobile Team Needs CI/CD and How to Build a Winning Strategy
    • Dart in 2024: 20 Features You Need to Know With Code Examples and Scenarios
    • Remote Theme Management with API (JSON): Implementing a Helper in Flutter SDK
    • Understanding and Implementing Force Upgrade in Your Flutter Project
    • Life Lessons from the Bald Eagle: A Metaphor for Growth, Change, and Leadership
    • The Beauty of Imperfection: Why Today Doesn’t Need to Be Perfect
    • # The Reverse Curve of Productivity: When Social Cohesion in Software Teams Starts to Hurt **How str
    • 📱 Mobil Uygulamalarda GraphQL Tercihi: Bakım ve Maliyet Etkiler
    • 📉 Türkiye’de Yazılım Projelerinde Süreç Yönetimi ve Ekonomik Kayıp: Bir Bekâ Sorunu mu?
  • 📹VIDEOS
    • Introduction to Flutter Boilerplate! ( Turkish )
    • Flutter APIs effective using ( English )
    • Understand to SDK ( English )
  • Links
    • 💼 | Linkedin
    • 🆇 | x.com
    • 📧 | Mail me
Powered by GitBook
On this page
  1. Guidances

📱 Mobil Uygulamalarda GraphQL Tercihi: Bakım ve Maliyet Etkiler

Previous# The Reverse Curve of Productivity: When Social Cohesion in Software Teams Starts to Hurt **How strNext📉 Türkiye’de Yazılım Projelerinde Süreç Yönetimi ve Ekonomik Kayıp: Bir Bekâ Sorunu mu?

Last updated 1 month ago

Mobil uygulama geliştirme, RESTful API’lerin sunduğu standartların ötesinde bir esnekliğe ve optimizasyona ihtiyaç duyar. Özellikle veri trafiği maliyetleri, backend-frontend bağımlılıkları ve performans optimizasyonu gibi kritik konularda, GraphQL REST’e kıyasla kazanımlarıyla öne çıkıyor. Bu makalede, GraphQL’in mobil uygulamalarda neden tercih edilmesi gerektiğini mühendislik algoritmaları, maliyet analizi ve Bloc tabanlı mimari ile detaylandıracağız.


GraphQL vs REST: Mobil Uygulamalar İçin Karşılaştırma

Kriter

GraphQL (Olumlu)

GraphQL (Olumsuz)

REST (Olumlu)

REST (Olumsuz)

Veri Trafiği

Tek sorguda tam ihtiyaç duyulan veri (over-fetching yok).

Kötü optimize edilmiş sorgular over-fetching’e yol açabilir.

Basit endpoint’lerle hızlı erişim.

Çoklu endpoint’ler gerektiğinde over/under-fetching kaçınılmaz.

Backend Bağımlılığı

Frontend, backend’den bağımsız veri şekillendirebilir (Bloc mimarisiyle uyumlu).

Schema yönetimi ve optimizasyon için backend’de ekstra çaba gerekir.

Standart HTTP metodlarıyla basit entegrasyon.

API değişikliklerinde frontend-backend sıkı senkronizasyon gereklidir.

Performans

Tek istekte çoklu kaynak çekme (network round-trip’i azaltır).

Büyük sorgular sunucu tarafında performansı düşürebilir.

Cache mekanizması HTTP standartlarıyla kolay uygulanabilir.

Çoklu isteklerde performans düşer (özellikle düşük bant genişliğinde).

Maliyet

Azaltılmış veri trafiği (mobil kullanıcılar için düşük maliyet).

Sunucu tarafı optimizasyonu için ek mühendislik maliyeti.

Basit mimari, düşük geliştirme maliyeti.

Aşırı veri transferi yüksek maliyetlere yol açabilir.

Öğrenme Eğrisi

Mühendislerin algoritmik sorgu optimizasyonu becerilerini geliştirir.

GraphQL syntax ve schema tasarımı yeni başlayanlar için karmaşık gelebilir.

REST, basitliği ve yaygın kullanımı nedeniyle kolay öğrenilir.

API versioning ve endpoint yönetimi zamanla karmaşıklaşabilir.


"GraphQL, ‘Ben bir kahve istiyorum, kahve çekirdeğini Brezilya’dan getirip barista ayarlama’ diyen müşteri gibidir. REST ise ‘Espresso mu, Americano mu?’ diye sorar. Mobil geliştiricilerin çoğu, kahveyi kendi tarifleriyle almak ister… Tabii ödeyecek data parası varsa! ☕"


Yazılım dünyasında API tasarımının temel amacı, kullanıcıların değişen ve çeşitlenen ihtiyaçlarına etkili biçimde yanıt vermektir. Web’in yaygınlaşmasıyla birlikte ortaya çıkan REST mimarisi, evrensel erişim ve standartlaşma sağladı. Ancak günümüzde mobil uygulamaların artan esnekliği ve özel veri ihtiyaçları, yeni çözümler doğurmuştur. GraphQL gibi teknolojiler, bu evrimin bir parçası olarak, geleneksel yaklaşımları geliştirerek modern taleplere daha iyi cevap verecek şekilde şekillenmiştir. Bu dönüşüm, teknolojinin gelişimine paralel olarak doğal bir süreci yansıtmaktadır.


📉 REST’in Mobilde Yarattığı Sorunlar ve Maliyetler

1. Aşırı Veri Transferi (Over-fetching)

  • Problem: REST’te bir endpoint, sabit veri yapısı döner. Mobilde düşük bant genişliği olan kullanıcılar için bu, gereksiz veri yükü demektir.

    // Örnek REST Yanıtı (Kullanıcı Profili)
    {
      "id": 1,
      "name": "Ali Mehmet",
      "email": "[email protected]",
      "address": "...", // Mobilde gereksiz!
      "orders": [ ... ] // Mobilde gereksiz!
    }

2. Çoklu İstekler (Under-fetching)

  • Problem: Bir ekranı doldurmak için birden fazla API isteği gerekiyorsa, mobilde latency artar ve pil tüketimi yükselir.

    // Örnek: REST ile 3 farklı endpoint çağrısı
    final user = await getUser();
    final posts = await getPosts(user.id);
    final comments = await getComments(user.id);

3. Sürüm Yönetimi ve Bakım Zorluğu

  • Problem: REST’te endpoint sürümleri (/v1/users, /v2/users) mobildeki eski uygulama versiyonlarıyla uyumsuzluk yaratır.

  • Maliyet: Her sürüm değişikliği, mobil ekiplerde +20 saat bakım süresi ekler.


🚀 GraphQL’in Mobildeki Teknik ve Ekonomik Avantajları

1. İstemci Odaklı Sorgular ile Maliyet Optimizasyonu

  • Algoritma: GraphQL sorguları, AST (Abstract Syntax Tree) ile parse edilir ve yalnızca istenen alanları çeker.

    query MobileUserProfile {
      user(id: "123") {
        name
        profileImage
      }
    }
  • Ekonomik Kazanım: Veri transferi %60-70 azalır. 1M kullanıcılı bir uygulamada aylık $5K-$10K tasarruf sağlar.

2. Tek İstekte Çoklu Veri (Batch Query)

  • Algoritma: GraphQL’de @export ve @defer direktifleri ile tek sorguda çoklu veri çekilebilir.

    query HomeScreenData {
      user(id: "123") {
        name
        posts(first: 5) {
          title
          likes
        }
      }
      trendingTopics {
        name
      }
    }
  • Performans Kazanımı: Ağ gecikmesi (latency) %50 düşer.

3. Otomatik Önbellekleme ile CPU/Batarya Verimliliği

  • Algoritma: Apollo Client gibi araçlar, normalize edilmiş cache yapısıyla veriyi yerel depoda tutar.

    // Örnek: Cache politikası (Bloc ile entegre)
    final client = GraphQLClient(
      cache: GraphQLCache(
        dataIdFromObject: (object) => object['id'], // Normalizasyon
      ),
    );
  • Mobil Etkisi: CPU kullanımı %20 azalır, pil ömrü uzar.

4. Şema Tabanlı Güvenlik ve Bakım Kolaylığı

  • Algoritma: GraphQL şeması, Introspection Query ile dokümante edilir. Mobil ekipler, backend’i beklemek yerine mock schema ile çalışabilir.

  • Bakım Süresi: Geliştirme süresi %40 kısalır.


🔧 Bloc Tabanlı Mimaride GraphQL Entegrasyonu

1. Proje Yapısı

lib/
├── core/
│   ├── config/         # GraphQL client
│   └── utils/         # Query builder
├── data/
│   ├── models/        # Freezed
│   ├── repositories/  # GraphQL operations
└── presentation/
    ├── cubits/        # Business logic
    ├── widgets/
    └── pages/

2. Bloc ile Sorgu Yönetimi

// data/repositories/post_repository.dart
class PostRepository {
  final GraphQLClient _client;

  PostRepository(this._client);

  Future<List<Post>> getPosts() async {
    const query = '''
      query GetPosts {
        posts {
          id
          content
          likes
        }
      }
    ''';

    final result = await _client.query(QueryOptions(document: gql(query)));
    return Post.fromJsonList(result.data!['posts']);
  }
}

// presentation/cubits/post_cubit.dart
class PostCubit extends Cubit<PostState> {
  final PostRepository _repo;

  PostCubit(this._repo) : super(PostInitial());

  Future<void> fetchPosts() async {
    emit(PostLoading());
    try {
      final posts = await _repo.getPosts();
      emit(PostLoaded(posts));
    } catch (e) {
      emit(PostError('Failed to fetch posts'));
    }
  }
}

3. Optimistik Güncelleme Algoritması

// presentation/cubits/like_cubit.dart
class LikeCubit extends Cubit<LikeState> {
  final GraphQLClient _client;

  LikeCubit(this._client) : super(LikeInitial());

  Future<void> likePost(String postId) async {
    emit(LikeProcessing(postId));
    
    // Optimistik update
    final mutation = gql('''
      mutation LikePost(\$postId: ID!) {
        likePost(postId: \$postId) {
          id
          likes
        }
      }
    ''');

    try {
      await _client.mutate(MutationOptions(
        document: mutation,
        variables: {'postId': postId},
        update: (cache, result) {
          // Cache güncelleme
          final post = cache.readQuery(...);
          cache.writeQuery(...);
        },
      ));
      emit(LikeSuccess(postId));
    } catch (e) {
      emit(LikeFailed(postId));
    }
  }
}

📊 Maliyet ve Bakım Endeksi Karşılaştırması

Metrik
REST
GraphQL

Aylık Veri Transferi

10 TB

3.5 TB

Sunucu Maliyeti

$12,000

$6,500

Geliştirme Süresi

200 Saat

120 Saat

Bakım Süresi (Aylık)

50 Saat

20 Saat


🔐 Güvenlik ve Optimizasyon Algoritmaları

  1. Sorgu Derinlik Sınırı:

    final client = GraphQLClient(
      link: Link.from([
        DepthLink(maxDepth: 5), // Sorgu derinliğini 5 ile sınırla
        httpLink,
      ]),
    );
  2. Persisted Queries: Sık kullanılan sorguları hash’leyerek CDN’e alın.

  3. Rate Limiting:

    # Şema tanımı
    directive @rateLimit(
      max: Int
      window: String
    ) on FIELD_DEFINITION
    
    type Query {
      getPosts: [Post!]! @rateLimit(max: 100, window: "1m")
    }

🚨 Mobilde Dikkat Edilmesi Gerekenler – API ve Performans Perspektifiyle

  1. Offline Öncelikli Tasarım: Mobil ağ bağlantısı her zaman güvenilir değildir. Kullanıcı deneyimini kesintisiz sürdürmek için GraphQL istemcilerinde (örneğin Apollo veya Hive) cache’i persist edecek şekilde yapılandırmak önemlidir. Bu sayede, ağ bağlantısı olmasa bile uygulama kısıtlı da olsa çalışmaya devam edebilir.

  2. Sorgu Sıklığı ve Batarya Optimizasyonu: Mobil cihazlarda gereksiz ağ çağrıları batarya tüketimini artırır. Batching (çoklu sorguların tek bir istekte toplanması) ve debouncing (sık çağrıları geciktirerek tekilleştirme) teknikleri kullanılarak enerji verimliliği sağlanabilir.

  3. Büyük Dosya Yüklemeleri: Mobil ağlar genellikle yavaş ve sınırlıdır. Büyük dosya yüklemeleri için REST kullanmak veya GraphQL Upload protokolüyle dosyaları küçük parçalara (chunk’lara) bölerek yüklemek daha sağlıklı sonuç verir.

  4. Düşük Gecikmeli Veri Erişimi: Kullanıcıya hızlı geri bildirim vermek kritiktir. Kritik veriler için yerel cache öncelikli, arka planda güncellenen bir mimari tercih edilebilir (örneğin stale-while-revalidate).

  5. Yavaş Ağ Koşullarında Uyum: Ağ hızı düşük olduğunda kullanılacak veri miktarını azaltmak gerekir. GraphQL’de bu, yalnızca ihtiyaç duyulan alanları sorgulayarak sağlanabilir. REST’te ise endpoint’leri sadeleştirmek gerekebilir.

  6. Error Handling ve Retry Mekanizmaları: Mobilde ağ hataları sık yaşanır. Bu yüzden isteklerin otomatik olarak yeniden denenmesi (retry logic) ve kullanıcıya dostça hata mesajları gösterilmesi önemlidir.

  7. Push Notification ile Veri Güncelleme: Uygulamanın arka planda sürekli veri çekmesini engellemek için WebSocket ya da push notification destekli veri güncelleme yöntemleri tercih edilebilir. Bu da hem batarya hem ağ verimliliği sağlar.

  8. Güvenli ve Hafif Kimlik Doğrulama: Mobil cihazlar için token tabanlı kimlik doğrulama sistemleri (örneğin JWT) tercih edilmeli ve refresh token mekanizması güvenli bir şekilde uygulanmalıdır. Gereksiz token refresh isteklerinden kaçınılmalıdır.

  9. Versiyonlama Stratejisi: Mobil uygulamalar kullanıcı tarafından güncellenmeyebilir. Bu nedenle API’lerin geriye dönük uyumluluğu korunmalı veya versiyonlama (REST’te URI üzerinden, GraphQL’de schema branching gibi) stratejileri uygulanmalıdır.

  10. Arka Plan Veri Eşitleme: Kullanıcı uygulamayı kullanmadığında dahi verilerin eşitlenmesi gerekebilir. Bu durumlarda düşük öncelikli, enerji dostu arka plan görevleri (background sync) planlanmalıdır.


🎯 Sonuç: GraphQL Mobil Ekosistem İçin Neden Kritik?

  1. 🔌 Veri Transferinde Verimlilik: GraphQL, yalnızca ihtiyaç duyulan alanları sorgulama imkânı sunduğu için REST’e kıyasla %50-70’e kadar daha az veri transferi sağlar. Bu, özellikle mobilde sınırlı bant genişliği ve veri paketleri açısından çok daha ekonomiktir.

  2. 💰 Sunucu Maliyetlerinde Azalma: Azalan veri trafiği ve optimize sorgular, sunucu üzerindeki işlem yükünü azaltır. Bu da arka uç servisleri için ölçeklenebilirliği artırır ve maliyetleri düşürür.

  3. ⚙️ Reaktif State Yönetimi ile Entegrasyon: Bloc veya Riverpod gibi modern Flutter state yönetimi çözümleri, GraphQL ile kolayca entegre edilebilir. Bu entegrasyon sayesinde veri akışı ve kullanıcı arayüzü arasında tutarlı, reaktif bir yapı kurulur.

  4. 📶 Ağ Optimizasyonu: GraphQL, Batching, Caching ve Debouncing gibi mekanizmalarla tek istekte çok sayıda veri ihtiyacını karşılayabilir. Bu da mobilde ağ çağrılarını azaltarak enerji tasarrufu ve performans sağlar.

  5. 🧩 Tip Güvenliği ve Otomatik Kod Üretimi: GraphQL şemaları sayesinde tip güvenliği sağlanır. Ayrıca codegen araçları ile otomatik olarak veri modelleri, sorgular ve hata tipleri üretilebilir, bu da geliştirme hızını artırır ve hata payını azaltır.

  6. 📲 Gerçek Zamanlı Veri Desteği: GraphQL’in sunduğu Subscription yapısıyla mobil uygulamalarda WebSocket üzerinden gerçek zamanlı güncellemeler almak mümkündür. Bu da sohbet, canlı skor, bildirim gibi senaryolarda kullanıcı deneyimini iyileştirir.

  7. 🛠 Tek Endpoint, Daha Az Karmaşa: GraphQL’in tek endpoint yapısı sayesinde çok sayıda REST endpoint’ine ihtiyaç kalmaz. Bu, hem istemci hem de sunucu tarafında kodun daha sade ve sürdürülebilir olmasını sağlar.

  8. 🔁 Daha Kolay Versiyonlama ve Evrim: GraphQL şemaları geliştiricilere alan bazlı versiyonlama esnekliği tanır. Geriye dönük uyumluluk daha rahat korunabilir, bu da mobilde uygulamanın eski sürümlerine destek vermeyi kolaylaştırır.

  9. 🚀 Geliştirme Sürecinde Hız ve Esneklik: Geliştiriciler ihtiyaç duydukları verileri özgürce tanımlayabildiği için ön uç geliştirme süreçleri arka uçtan daha az bağımlı hale gelir. Bu da ekiplerin daha çevik çalışmasını sağlar.

  10. ✨ Daha Yüksek Kullanıcı Memnuniyeti: Hızlı veri yükleme, düşük gecikme süresi, az hata ve stabilite sayesinde kullanıcı deneyimi artar. Mobil kullanıcılar için bu, uygulamanın kullanılabilirliğini ve sadakatini doğrudan etkiler.


Başlamak İçin:

Mobil uygulamaların geleceği, veri etkileşiminin akıllıca yönetildiği GraphQL tabanlı mimarilerde şekillenecek. ⚡

- Gurkan

Maliyet: Gereksiz veri transferi, kullanıcı başına %20-40 daha fazla data tüketimi anlamına gelir (Kaynak: ).

Maliyet: Her ekstra istek, sunucu maliyetlerini %10-15 artırır (Kaynak: ).

📄
AWS
AWS Fiyatlandırma
GitHub Örnek Proje
GraphQL Best Practices