Riverpod Code Generation İle Çalışmak

Bu yazıda Riverpod kütüphanesinin code generation modülünü kullanarak, Flutter’da state/network işlemleri nasıl yapılır anlatacağım. Uzun bir süredir yazı girmediğimi fark ederek ve Flutter topluluğuna katkı sunamadığım için kendimi kötü hissediyordum. 1 yıldır Flutter projelerimde Riverpod kullandığımdan, bu yazıda Riverpod üzerinden state işlemleri nasıl gerçekleştirilir bunu anlatacağım.

Kullanacağım API, Fake Store API. Eğer dilerseniz siz de bu kaynağı Flutter uygulamalarınızda mock data için kullanabilirsiniz.

Şu modülleri ekleyerek projeye başlayabiliriz:

  flutter_riverpod: ^2.4.9
  riverpod_generator: ^2.3.9
  riverpod_annotation: ^2.3.3
  http: ^1.1.0

dev_dependencies:
  build_runner: ^2.4.7

Projenin Dosya Yapısı

Projenin dosya yapısı şu şekilde olacaktır:

lib/
┣ features/
┃ ┣ product_detail/
┃ ┃ ┣ domain/
┃ ┃ ┃ ┗ product_detail_domain.dart
┃ ┃ ┣ models/
┃ ┃ ┃ ┣ product_detail_rating_response_model.dart
┃ ┃ ┃ ┗ product_detail_response_model.dart
┃ ┃ ┣ presentation/
┃ ┃ ┃ ┗ product_detail_screen.dart
┃ ┃ ┗ service/
┃ ┃   ┗ product_detail_service.dart
┃ ┗ product_list/
┃   ┣ domain/
┃ ┃ ┃ ┗ products_domain.dart
┃   ┣ models/
┃ ┃ ┃ ┗ product_response_model.dart
┃   ┣ presentation/
┃ ┃ ┃ ┗ product_list_screen.dart
┃   ┣ service/
┃ ┃ ┃ ┗ product_list_service.dart
┃   ┗ widgets/
┃ ┃   ┗ product_list_container.dart
┗ main.dart

Bu şekilde klasörlemenin yapısını çıkarmak için File Tree to Text Generator eklentisini kullanabilirsiniz. 🙂

Servis Kodlarının Yazılması

product_list_service.dart

Öncelikle tüm ürünlerin çekileceği API isteğini gönderelim ve gelen veriyi ayıklayalım.

product_detail_service.dart

Daha sonrasında ürün detayını çekeceğimiz API isteğini yazalım ve gelen veriyi düzenleyelim.

Domain Kodlarının Yazılması

Riverpod belirteçi ile, hızlıca fonksiyonumuzu oluşturalım. Hızlıca oluşturmak için, Flutter Riverpod Snippets isimli eklentiyi ortamınıza kurabilirsiniz. Eğer bu eklentiyi kurarsanız, size yazdıkça öneri sunacaktır ve bazı yapıları hızlıca oluşturmanızı sağlayacaktır. Aşağıda videolu örneğe bakabilirsiniz.

Yukarıyı örnek olarak vermiştim. Aşağıda product_list ve product_detail için gereken kodları paylaşıyorum.

Code Generation İşlemi

@riverpod annotation’ı kullanarak yazdığımız fonksiyonları, provider’a çevirelim. Öncelikle product_list_domain.dart içerisine generate edilecek kodun bulunacağı lokasyonu, importların altına yazalım:

part 'products_domain.g.dart';

Daha sonrasında product_detail_domain.dart altına benzer importu yazalım.

part 'product_detail_domain.g.dart';

Daha sonrasında build_runner’ı çalıştırarak, riverpod fonksiyonlarını generate edelim.

dart run build_runner watch

Her şey doğru olduğunda aşağıdaki gibi bir çıktı sizi bekliyor olacak. Bu aşamada, komut succeeded olduğunda Mac’te Ctrl+Z yaparak komutu durdurabilirsiniz.


Code Generation’ı çalıştırdığımıza göre, iki farklı dosya eklenmiş olmalıdır: ‘products_domain.g.dart‘ ve ‘product_detail_domain.g.dart‘ isimli iki dosya. Bu iki dosyada yer alan generate edilmiş providerlar, daha önceden bizim yaptığımız futureProvider veya stateProvider gibi işlemleri yapmakta fakat bir farkla! Static Metaprogramming özelliği Dart diline eklendiğinde Riverpod Code Generation, Riverpod kullanımı için tek seçenek olacak. Aşağıda Riverpod dökümanlarından aldığım alıntıda bu kesin olarak belirtilmiş:

Currently, code generation is optional because build_runner is disliked by many. But once Static Metaprogramming is available in Dart, build_runner will no longer be an issue. At that point, the code generation syntax will be the only syntax available in Riverpod.

Riverpod Docs – About Code Generation

Static Metaprogramming nedir bir başka yazının konusu. Biz şimdilik Flutter’da projemizi tamamlayalım. 🙂



Presentation Kodlarının Yazılması

ProductListScreen içerisinde yazdığım kodlar şu şekilde:

product_list_screen.dart

Daha öncesinde fetchProductListProvider diye bir şey yazmamış olsak da, generate edilmiş kodumuzda böyle bir provider bulunmakta. Bunun olmasının sebebi, Riverpod yazılan kodu analiz ederek, gereken providerı bizim adımıza oluşturmakta ve en optimum biçimde bunu yapmakta. Böylelikle artık hangi providerı kullanmamız gerektiğini düşünmemize gerek kalmayacak ve yalnızca @riverpod belirteçi ile kodumuzu yazacağız.

Çıkan sonuç:


Bir sonraki yazıda ürün detay sayfasını göstermeyi ve listeye dinamik olarak ürün ekleme, ürün silme, pagination gibi işlemleri yapacağım. Takipte kalmayı unutmayın. 🙂


Okuyucuya Not

Merhaba okuyucu! Blogum son zamanlarda yüksek trafik almaya başladı ve bu durumdan memnunum fakat aynı zamanda siz ziyaretçileri tatmin edememekten endişeliyim. 🙂 Eğer yazılarım ile ilgili bir tavsiyeniz olursa mail adresimden bana ulaşabilir veya Twitter üzerinden direct message gönderebilirsiniz.

Sağlıcakla kalın!