Flutter & Mobil İle Json Veri İşleme Ve Ayrıştırma Nasıl Yapılır?

Flutter & Mobil İle Json Veri İşleme Ve Ayrıştırma Nasıl Yapılır?
Flutter & Mobil İle Json Veri İşleme Ve Ayrıştırma Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu eğitimi takip edebilmeniz için bilgisayarınızda Flutter SDK'nın 3.20 veya daha güncel bir sürümünün yüklü olması gerekmektedir. Ayrıca, VS Code veya Android Studio gibi bir editör ve temel Dart programlama bilgisi yeterlidir.

  • Flutter SDK: 3.20+ sürümü.
  • Dart: 3.5+ sürümü (Records ve Pattern Matching özellikleri için).
  • Paketler: json_serializable ve build_runner kütüphaneleri.

Manuel JSON Ayrıştırma Yöntemi

Küçük ölçekli projelerde veya çok basit veri yapılarında, Dart'ın yerleşik dart:convert kütüphanesi ile manuel ayrıştırma yapabilirsiniz. Bu yöntem, harici bir paket bağımlılığı oluşturmadığı için hızlı sonuç verir ancak büyük veri setlerinde hata yapma riskini artırır.

import 'dart:convert';

void main() {
  String jsonVeri = '{"id": 1, "isim": "Flutter Geliştirici", "aktif": true}';
  Map kullanici = jsonDecode(jsonVeri);

  print('Kullanıcı Adı: ${kullanici['isim']}');
}

Yukarıdaki örnekte jsonDecode fonksiyonu, gelen String ifadeyi bir Map yapısına dönüştürür. Anahtarlar üzerinden verilere doğrudan erişim sağlayabilirsiniz. Ancak bu yöntem tip güvenli (type-safe) değildir; yanlış anahtar ismi yazarsanız çalışma anında (runtime) hata alırsınız.

Model Sınıfları ile JSON Ayrıştırma

Profesyonel uygulamalarda verileri Map olarak tutmak yerine, bunları Dart sınıflarına (Model) dönüştürmek en iyi pratiktir. Bu, kodun okunabilirliğini artırır ve IDE'nin otokomple (kod tamamlama) özelliğinden faydalanmanızı sağlar.

class Kullanici {
  final int id;
  final String isim;

  Kullanici({required this.id, required this.isim});

  factory Kullanici.fromJson(Map json) {
    return Kullanici(
      id: json['id'] as int,
      isim: json['isim'] as String,
    );
  }
}

fromJson fabrika kurucusu (factory constructor), JSON haritasını alıp sınıf örneğine dönüştürür. Bu sayede veriye kullanici.isim şeklinde erişebilirsiniz.

json_serializable ile Otomatik Kod Üretimi

Projeniz büyüdüğünde her model için manuel fromJson yazmak zaman kaybıdır. json_serializable paketi, sınıflarınızın üzerine ekleyeceğiniz anotasyonlarla bu kodları sizin yerinize üretir.

Öncelikle pubspec.yaml dosyanıza gerekli bağımlılıkları ekleyin:

dependencies:
  json_annotation: ^4.9.0

dev_dependencies:
  build_runner: ^2.4.0
  json_serializable: ^6.8.0

Ardından model sınıfınızı şu şekilde tanımlayın:

import 'package:json_annotation/json_annotation.dart';

part 'kullanici.g.dart';

@JsonSerializable()
class Kullanici {
  final int id;
  final String isim;

  Kullanici(this.id, this.isim);

  factory Kullanici.fromJson(Map json) => _$KullaniciFromJson(json);
}

Bu koddan sonra terminalde dart run build_runner build komutunu çalıştırarak kullanici.g.dart dosyasının otomatik oluşturulmasını sağlayabilirsiniz.

JSON İşleme Yöntemleri Karşılaştırması

Yöntem Avantajı Dezavantajı
Manuel (Map) Bağımlılık yok, hızlı. Tip güvenliği yok, hataya açık.
Model Sınıfı Okunabilir, güvenli. Çok fazla boilerplate kod.
json_serializable Otomatik, hatasız, ölçeklenebilir. Kurulum gerektirir, build süreci var.

Güvenli Veri Ayrıştırma ve Hata Yönetimi

Sunucudan gelen verinin her zaman beklediğiniz formatta olacağını varsaymamalısınız. Eksik veya yanlış veri tipleri uygulamanızın çökmesine neden olabilir. Bu yüzden her zaman tip kontrolleri yapın.

factory Kullanici.fromJson(Map json) {
  return Kullanici(
    id: json['id'] as int? ?? 0, // Varsayılan değer atama
    isim: json['isim'] as String? ?? 'Bilinmiyor',
  );
}
Kritik Güvenlik Uyarısı: Sunucudan gelen verileri asla doğrudan UI katmanına (ekrana) yansıtmayın. Özellikle kullanıcı girdisi içeren JSON verilerini işlerken XSS (Cross-Site Scripting) riskine karşı veriyi temizlediğinizden (sanitization) emin olun. API anahtarlarınızı uygulama içine gömmeyin; bunları güvenli bir ortam değişkeni veya backend üzerinden yönetin.

Sıkça Sorulan Sorular

JSON verisi işlerken neden 'type mismatch' hatası alıyorum?

Bu hata genellikle JSON'daki veri tipi ile Dart sınıfındaki veri tipinin uyuşmamasından kaynaklanır. Örneğin, JSON'da "1" (String) olarak gelen bir değeri int olarak parse etmeye çalışıyorsanız bu hatayı alırsınız.

Büyük JSON dosyalarını nasıl daha performanslı işlerim?

Çok büyük JSON verileri için ana işlemciyi (main isolate) dondurmamak adına compute fonksiyonunu kullanın. Bu, ayrıştırma işlemini arka planda (background isolate) yapmanızı sağlar.

API'dan gelen boş değerleri (null) nasıl yönetmeliyim?

Dart'ta nullable (?) tipler kullanarak veya ?? operatörü ile varsayılan değerler atayarak null pointer hatalarının önüne geçebilirsiniz.

JSON verisi içinde tarih formatlarını nasıl işlerim?

JSON standartlarında tarih tipi yoktur, genellikle String olarak gelir. DateTime.parse() fonksiyonunu kullanarak bu String ifadeleri DateTime nesnesine dönüştürebilirsiniz.

Otomatik kod üretimi (build_runner) neden çalışmıyor?

Genellikle dosya isimlerinin part direktifi ile uyuşmamasından veya json_serializable paketinin güncel olmamasından kaynaklanır. flutter clean komutunu çalıştırıp tekrar deneyin.

İleri Seviye Veri Dönüşümü: JSON ve Freezed Kullanımı

Modern Flutter projelerinde, json_serializable kütüphanesinin sunduğu esnekliğin ötesine geçmek ve daha temiz bir veri modeli yapısı kurmak için freezed kütüphanesi tercih edilir. Freezed, veri modelleriniz için değişmezlik (immutability), copyWith metodu ve union türleri gibi gelişmiş özellikler sunarak JSON işleme sürecini hatasız hale getirir.

Aşağıdaki örnek, bir kullanıcı profilini hem JSON'dan dönüştüren hem de veri tutarlılığını garanti altına alan bir yapıyı göstermektedir:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user_model.freezed.dart';
part 'user_model.g.dart';

@freezed
class User with _$User {
  const factory User({
    required int id,
    required String name,
    @Default('Unknown') String email,
  }) = _User;

  factory User.fromJson(Map json) => _$UserFromJson(json);
}

Bu yapıyı kullanmanın en büyük avantajı, uygulamanın herhangi bir yerinde veriyi yanlışlıkla değiştirmenizin önüne geçilmesidir. copyWith metodu sayesinde, mevcut bir nesneden yola çıkarak sadece belirli alanları güncellenmiş yeni bir nesne oluşturabilirsiniz.

JSON Veri İşleme Sürecinde Birim Testi (Unit Testing)

JSON ayrıştırma mantığınızın doğruluğunu kanıtlamak için mutlaka birim testleri yazmalısınız. Özellikle API'dan gelen verinin yapısı değiştiğinde, uygulamanızın çökmesini önlemek için test paketini kullanmak profesyonel bir yaklaşımdır.

Aşağıdaki test örneği, bir JSON string'inin model sınıfına hatasız dönüştürülüp dönüştürülmediğini kontrol eder:

import 'package:test/test.dart';
import 'package:your_app/models/user_model.dart';

void main() {
  test('User modelinden JSON ayrıştırma testi', () {
    final jsonMap = {'id': 1, 'name': 'Ahmet', 'email': 'ahmet@test.com'};
    final user = User.fromJson(jsonMap);

    expect(user.id, 1);
    expect(user.name, 'Ahmet');
    expect(user.email, 'ahmet@test.com');
  });
}

Bu testleri CI/CD süreçlerinize dahil ederek, API tarafında yapılan güncellemelerin uygulamanızın veri katmanını bozup bozmadığını otomatik olarak takip edebilirsiniz. Test yazarken özellikle null değerlerin veya beklenen alanların eksik olduğu "edge case" durumlarını simüle etmeyi unutmayın.

Performans Optimizasyonu: Compute Kullanımı

Çok büyük boyutlu JSON dosyalarını (örneğin 5MB ve üzeri) ana thread üzerinde ayrıştırmak, uygulamanızda "jank" (kare atlama) sorunlarına ve arayüzün donmasına yol açar. Bu tür ağır işlemleri arka planda çalıştırmak için Flutter'ın compute fonksiyonunu kullanmalısınız.

import 'package:flutter/foundation.dart';
import 'dart:convert';

Future parseUsersInBackground(String jsonString) async {
  return compute(_parseUsers, jsonString);
}

List _parseUsers(String jsonString) {
  final parsed = jsonDecode(jsonString).cast();
  return parsed.map((json) => User.fromJson(json)).toList();
}

Bu yaklaşım, JSON ayrıştırma işlemini ayrı bir izole (isolate) içerisinde gerçekleştirir ve ana thread'in akıcılığını korur. Özellikle liste tabanlı veri setlerinde bu yöntem, kullanıcı deneyimini doğrudan iyileştiren kritik bir optimizasyondur.

Sonuç

Flutter & Mobil ile JSON veri işleme, uygulamanızın veri katmanını oluşturur. Manuel yöntemlerden başlayıp, json_serializable gibi profesyonel araçlara geçiş yapmak, projenizin uzun vadeli başarısı için kritiktir. Tip güvenliğine önem verin, hata yönetimi mekanizmalarını ihmal etmeyin ve her zaman veriyi doğrulamayı bir alışkanlık haline getirin.

Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamındaki uygulamalarınızda ağ güvenliği, veri şifreleme ve API kimlik doğrulama süreçleri için profesyonel güvenlik standartlarını (OAuth2, HTTPS vb.) uyguladığınızdan emin olun.

Bir sonraki adım olarak, Retrofit veya Dio gibi kütüphaneleri kullanarak API isteklerinizi nasıl otomatize edebileceğinizi araştırmanızı öneririm.

Bu yazıya tepkinizi paylaşın:
Zeynep Kaya

Yaşam kalitesini artıran hızlı ve etkili yöntemler üzerine içerik geliştiriyorum. Detaylara önem veren, çözüm odaklı rehberlerin öncüsüyüm.

Yorumlar (0)

Yorum Yaz