Mobil Geliştirme

GetX Nedir? Durum Yönetimi, Route ve Bağımlılık Enjeksiyonu (Örneklerle)

Ferhat Balaban · 25 Eki 2026

GetX, Flutter uygulamalarında durum yönetimi, sayfa geçişleri (route) ve bağımlılık enjeksiyonunu tek pakette toplayan bir kütüphane. pub.dev üzerinde get adıyla yayınlanıyor. Flutter'a yeni başlayanların çoğu önce GetX ile tanışıyor, çünkü az kodla çalışan bir yapı kurmanıza izin veriyor. Bu yazıda üç parçasını da çalışan örneklerle anlatıyorum, sonunda da ne zaman tercih edilmeli, ne zaman başka bir yola bakılmalı onu yazıyorum. Flutter'ı yeni öğreniyorsanız önce Flutter nedir yazısına göz atabilirsiniz.

GetX nedir, neden kullanılır?

Flutter tek başına bir arayüz kütüphanesi. Ekranlar arası geçiş, uygulama genelinde veri paylaşımı ve sınıfların birbirine nasıl verileceği gibi konularda sizi bir yöne zorlamıyor. GetX bu üç konuyu tek çatıda çözüyor:

  • Durum yönetimi: Veri değişince ekranın ilgili kısmı kendiliğinden yenilenir.
  • Route yönetimi: BuildContext kullanmadan sayfaya git, geri dön, dialog ve snackbar aç.
  • Bağımlılık enjeksiyonu: Bir sınıfı bir kez oluştur, uygulamanın her yerinden bul.

Kurulum tek komut:

flutter pub add get

Kurulum ve ilk ayar

GetX'in route ve snackbar gibi özelliklerini kullanmak için uygulamanın kökünde MaterialApp yerine GetMaterialApp kullanılır. Yalnız durum yönetimini kullanacaksanız MaterialApp ile de çalışır.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() => runApp(const Uygulama());

class Uygulama extends StatelessWidget {
  const Uygulama({super.key});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'GetX Örnek',
      home: const SayacSayfasi(),
    );
  }
}

GetX ile durum yönetimi

İki yaklaşım var: reaktif (Obx) ve basit (GetBuilder). Önce reaktif olanı görelim. Bir değişkenin sonuna .obs eklediğinizde o değişken "gözlemlenebilir" olur. Değiştiğinde Obx içindeki widget yeniden çizilir.

class SayacController extends GetxController {
  final sayac = 0.obs;

  void artir() => sayac.value++;
}

class SayacSayfasi extends StatelessWidget {
  const SayacSayfasi({super.key});

  @override
  Widget build(BuildContext context) {
    final c = Get.put(SayacController());

    return Scaffold(
      appBar: AppBar(title: const Text('Sayaç')),
      body: Center(
        child: Obx(() => Text('Tıklama: ${c.sayac.value}')),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: c.artir,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Burada sayfanın tamamı yeniden çizilmiyor, yalnız Obx içindeki Text güncelleniyor. Liste için RxList de aynı mantıkla çalışır: final urunler = <String>[].obs; tanımlayıp urunler.add('Kalem') dediğinizde liste kendiliğinden yenilenir.

GetBuilder ile basit durum yönetimi

Her değişkeni gözlemlenebilir yapmak istemezseniz update() çağırarak yenilemeyi kendiniz tetikleyebilirsiniz. Bellekte biraz daha hafiftir, ama yenilemeyi çağırmayı unutmamak size kalır.

class SepetController extends GetxController {
  final List<String> urunler = [];

  void ekle(String ad) {
    urunler.add(ad);
    update();
  }
}

// Ekranda:
GetBuilder<SepetController>(
  init: SepetController(),
  builder: (c) => Text('Sepette ${c.urunler.length} ürün var'),
)

Controller yaşam döngüsü

GetxController içinde onInit() controller oluşunca, onClose() bellekten atılırken çağrılır. API'den veri çekmek için onInit doğal yerdir, dinlediğiniz akışları kapatmak için de onClose kullanılır.

class UrunController extends GetxController {
  final urunler = <String>[].obs;
  final yukleniyor = true.obs;

  @override
  void onInit() {
    super.onInit();
    verileriGetir();
  }

  Future<void> verileriGetir() async {
    yukleniyor.value = true;
    await Future.delayed(const Duration(seconds: 1)); // API çağrısı yerine
    urunler.assignAll(['Kalem', 'Defter', 'Silgi']);
    yukleniyor.value = false;
  }
}

GetX ile route yönetimi

En çok sevilen yanı Navigator.of(context) yazmadan geçiş yapabilmek. İsimli route tanımlamak için getPages kullanılır. Yol parametresi de desteklenir.

GetMaterialApp(
  initialRoute: '/',
  getPages: [
    GetPage(name: '/', page: () => const AnaSayfa()),
    GetPage(name: '/urun/:id', page: () => const UrunDetay()),
  ],
)

Geçiş ve geri dönüş:

Get.to(() => const UrunDetay());   // sayfayı doğrudan aç
Get.toNamed('/urun/42');           // isimli route ile aç
Get.off(() => const AnaSayfa());   // mevcut sayfayı kapatıp aç
Get.offAllNamed('/');              // geçmişi temizleyip aç
Get.back();                        // geri dön

Detay sayfasında yol parametresini şöyle okursunuz:

class UrunDetay extends StatelessWidget {
  const UrunDetay({super.key});

  @override
  Widget build(BuildContext context) {
    final id = Get.parameters['id'];
    return Scaffold(
      appBar: AppBar(title: Text('Ürün $id')),
      body: Center(
        child: ElevatedButton(
          onPressed: Get.back,
          child: const Text('Geri'),
        ),
      ),
    );
  }
}

Dialog ve snackbar da context istemez:

Get.snackbar('Kaydedildi', 'Ürün sepete eklendi');
Get.defaultDialog(title: 'Emin misiniz?', middleText: 'Bu işlem geri alınamaz.');

GetX ile bağımlılık enjeksiyonu

Bir sınıfı (servis, controller) bir kez kaydedip her yerden bulma işine bağımlılık enjeksiyonu denir. GetX'te üç temel komut var:

  • Get.put(...): Nesneyi hemen oluşturur ve kaydeder.
  • Get.lazyPut(() => ...): İlk kullanıldığı anda oluşturur. Açılış süresi için daha iyi.
  • Get.find<T>(): Kayıtlı nesneyi getirir.
class ApiServisi extends GetxService {
  Future<List<String>> urunleriGetir() async {
    return ['Kalem', 'Defter'];
  }
}

void main() {
  Get.put(ApiServisi(), permanent: true);
  runApp(const Uygulama());
}

// Başka bir yerde:
final api = Get.find<ApiServisi>();

Binding ile sayfaya özel bağımlılık

Controller'ı sayfa açılırken oluşturup sayfa kapanınca bellekten atmak için Binding kullanılır. Böylece sayfa kodunda Get.put yazmazsınız.

class UrunBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<UrunController>(() => UrunController());
  }
}

GetPage(
  name: '/urunler',
  page: () => const UrunListesi(),
  binding: UrunBinding(),
)

class UrunListesi extends GetView<UrunController> {
  const UrunListesi({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Obx(() => controller.yukleniyor.value
          ? const Center(child: CircularProgressIndicator())
          : ListView(
              children: controller.urunler
                  .map((u) => ListTile(title: Text(u)))
                  .toList(),
            )),
    );
  }
}

GetView<T>, ilgili controller'a controller adıyla doğrudan erişmenizi sağlayan hazır bir widget'tır.

Sık yapılan hatalar

  • Obx içinde gözlemlenebilir değer okumamak. Obx içinde hiç .obs değişkeni okunmazsa Get bunu hata olarak bildirir. Değer .value ile okunmalı.
  • Her şeyi permanent yapmak. Kalıcı kayıtlar bellekte kalır. Yalnız gerçekten uygulama boyu lazım olan servisleri kalıcı yapın.
  • İş mantığını widget'a gömmek. Hesap, API çağrısı ve karar mantığı controller'da olmalı. Widget yalnız göstermeli.
  • Kaydı yapılmamış servisi bulmaya çalışmak. Get.find kayıtsız bir tip için hata verir. Kaydı main ya da binding'de yaptığınızdan emin olun.

GetX mi, Riverpod mu, Bloc mu?

Üçü de üretimde kullanılıyor ve doğru cevap ekibe ve projeye göre değişiyor. GetX az kodla hızlı sonuç verir, küçük ve orta ölçekli uygulamalarda ve prototiplerde rahat çalışır. Büyük ekiplerde, katı katman ayrımı ve yüksek test edilebilirlik isteyen projelerde Riverpod ya da Bloc daha disiplinli bir yapı sunar. GetX'in her şeyi tek pakette toplaması kolaylık olduğu kadar bağımlılığı da artırır. Yeni bir projede seçim yaparken paketin güncel bakım durumuna pub.dev'den bakmanızı, ekibin alışık olduğu yapıyı da hesaba katmanızı öneririm.

Benim yaklaşımım, kararı projenin ömrüne ve ekibine göre vermek. Kısa ömürlü bir MVP ile yıllarca sürecek bir kurumsal uygulama aynı mimariyi gerektirmiyor. Flutter'ı başka çatılarla kıyaslayan bir yazı için Flutter mı React Native mi yazısına bakabilirsiniz.

Sık sorulan sorular

GetX öğrenmesi kolay mı?

Evet, temel kullanımı birkaç saatte oturur. Zorluk, proje büyürken klasör yapısını ve controller sınırlarını düzenli tutmakta çıkıyor.

GetX hâlâ kullanılıyor mu?

Evet, pek çok uygulamada kullanılıyor. Yine de her paket için olduğu gibi seçmeden önce pub.dev'deki son sürüm tarihine ve açık sorunlara bakmak doğru bir alışkanlık.

GetX ile Provider arasındaki fark nedir?

Provider yalnız durum paylaşımına odaklanır ve Flutter'ın widget ağacına dayanır. GetX ise route ve bağımlılık enjeksiyonunu da içerir ve BuildContext gerektirmez.

Flutter projeniz için destek

Mimari seçimi, mevcut bir Flutter uygulamasını düzene sokmak ya da sıfırdan yeni bir uygulama geliştirmek için Flutter mobil uygulama hizmetime ve Flutter uygulama geliştirme sayfasına göz atabilirsiniz. Neler yapılabildiğini merak ediyorsanız Flutter ile neler yapılabilir yazısı iyi bir başlangıç. Projenizi kısaca iletişim formundan ya da WhatsApp'tan yazın, kapsama göre kalemli bir teklif paylaşayım.

#Flutter #getx #Dart #Durum Yönetimi