Freezed Kullanarak Flutter'da JSON Nasl Ayrtrlr?
Bir nceki makalede, Dart'ta JSON' type-safe model snflarna nasl ayrtracamz rendik.
Ancak, ok sayda model snfmz varsa, tm JSON ayrtrma kodunu elle yazmak zaman alc ve hataya ak hale gelir. Neyse ki, sreci otomatikletirmek iin json_serializable ve Freezed gibi kod oluturma aralarn kullanabiliriz .
Bu yazda, Freezed paketini kullanarak kod oluturma (code generation) ile JSON verilerinin nasl ayrtrlacan reneceiz .
ncelikle pubspec.yaml dosyasna aadaki bamllklar eklememiz gerekiyor.
dependencies: flutter: sdk: flutter freezed_annotation: ^1.1.0 json_annotation: ^4.4.0dev_dependencies: build_runner: ^2.1.7 freezed: ^1.1.1 json_serializable: ^6.1.4
json_serializable
: Dart snflarna aklama ekleyerek JSON'a ve JSON'dan dntrme iin otomatik olarak kod oluturun
json_annotation
: "json_serializable" paketi araclyla JSON kodu oluturmay destekleyen snflar ve yardmc ilevler salar.
freezed
: basit bir API ile karmak kullanm durumlarn ileyebilen gl bir kod oluturucu.
freezed_annotation
: freezed tarafndan kullanlan aklamalar tanmlar.
build_runner
: Dart dosyalar oluturabilen bamsz bir derleme paketidir.
JSON ayrtrma kodunu yalnzca json_serializable ile (freezed kullanmadan) oluturabilirsiniz. Ancak, freezed daha gldr ve basit bir API ile karmak kullanm durumlarnn stesinden gelebilir.
rnek bir JSON belgesi
leri nceki makaleyle uyumlu tutmak iin ayn JSON rneini yeniden kullanacaz:
{ "name": "Pizza da Mario", "cuisine": "Italian", "year_opened": 1990, "reviews": [ { "score": 4.5, "review": "The pizza was amazing!" }, { "score": 5.0, "review": "Very friendly staff, excellent service!" } ]}
Daha nce yazdmz Restaurant ve Review model snflar unlardr:
class Restaurant { Restaurant({ required this.name, required this.cuisine, this.yearOpened, required this.reviews, }); final String name; final String cuisine; final int? yearOpened; final List<Review> reviews; factory Restaurant.fromMap(Map<String, dynamic> data) { final name = data['name'] as String; final cuisine = data['cuisine'] as String; final yearOpened = data['year_opened'] as int?; final reviewsData = data['reviews'] as List<dynamic>?; final reviews = reviewsData != null ? reviewsData.map((reviewData) => Review.fromMap(reviewData)).toList() : <Review>[]; return Restaurant( name: name, cuisine: cuisine, yearOpened: yearOpened, reviews: reviews, ); } Map<String, dynamic> toMap() { return { 'name': name, 'cuisine': cuisine, if (yearOpened != null) 'year_opened': yearOpened, 'reviews': reviews.map((review) => review.toMap()).toList(), }; }}
class Review { Review({required this.score, this.review}); final double score; // nullable - assuming the review may be missing final String? review; factory Review.fromMap(Map<String, dynamic> data) { final score = data['score'] as double; final review = data['review'] as String?; return Review(score: score, review: review); } Map<String, dynamic> toMap() { return { 'score': score, if (review != null) 'review': review, }; }}
Grld gibi ok fazla kod var ve birok fakl modelimiz varsa bu yaklam leklenemez.
Freezed ile Model Snflar
Hayatmz kolaylatrmak iin, Restaurant ve Review model snflarmz tanmlamak iin Freezed'i kullanalm.
Restaurant Review modeline bal olduundan, Review snfyla balayalm:
// review.dart// 1. import freezed_annotationimport 'package:freezed_annotation/freezed_annotation.dart';// 2. 'part' dosyalarn eklepart 'review.freezed.dart';part 'review.g.dart';// 3. @freezed annotation ekle@freezed// 4. mixin ile bir snf tanmlaynclass Review with _$Review { // 5. bir factory constructor tanmlayn factory Review({ // 6. tm argmanlar/zellikleri listele required double score, String? review, }) = _Review; // 7. json'dan ayrtrlacak baka bir factory constructor tanmlayn factory Review.fromJson(Map<String, dynamic> json) => _$ReviewFromJson(json);}
Aynsn Restaurant snf iin de yapalm:
// restaurant.dartimport 'package:freezed_annotation/freezed_annotation.dart';// baml olduumuz dier modelleri ie aktarnimport 'review.dart';part 'restaurant.freezed.dart';part 'restaurant.g.dart';@freezedclass Restaurant with _$Restaurant { factory Restaurant({ required String name, required String cuisine, @JsonKey(name: 'year_opened') int? yearOpened, // not: varsaylan deer olarak bo bir liste kullanmak @Default([]) List<Review> reviews, }) = _Restaurant; factory Restaurant.fromJson(Map<String, dynamic> json) => _$RestaurantFromJson(json);}
Hem Restaurant hem de Review snflarnn, ihtiyacmz olan tm argmanlar listeleyen bir factory constructor'a sahip olduuna dikkat edin, ancak ilgili zellikleri bildirmedik.
Aslnda kodumuz eksik ve aadaki gibi hatalar retecek:
Target of URI doesn't exist: 'restaurant.freezed.dart'.Try creating the file referenced by the URI, or Try using a URI for a file that does exist.The name '_Restaurant' isn't a type and can't be used in a redirected constructor.Try redirecting to a different constructor.The method '_$RestaurantFromJson' isn't defined for the type 'Restaurant'.Try correcting the name to the name of an existing method, or defining a method named '_$RestaurantFromJson'.
Kod oluturucuyu altrma
Eksik kodu oluturmak iin bunu konsolda altrabiliriz:
flutter pub run build_runner build --delete-conflicting-outputs
Bu, aadaki kty retecektir:
[INFO] Generating build script...[INFO] Generating build script completed, took 419ms[INFO] Initializing inputs[INFO] Reading cached asset graph...[INFO] Reading cached asset graph completed, took 55ms[INFO] Checking for updates since last build...[INFO] Checking for updates since last build completed, took 428ms[INFO] Running build...[INFO] 1.3s elapsed, 0/2 actions completed.[INFO] Running build completed, took 2.1s[INFO] Caching finalized dependency graph...[INFO] Caching finalized dependency graph completed, took 27ms[INFO] Succeeded after 2.1s with 5 outputs (5 actions)
Proje gezginine bakarsak, baz yeni dosyalar bulabiliriz:
restaurant.dartrestaurant.freezed.dartrestaurant.g.dartreview.dartreview.freezed.dartreview.g.dart
Her model snf iin kod oluturucu unlar ekler:
toString() yntemi
== operatr
hashCode getter deikeni
copyWith() yntemi
toJson() yntemi
Ve eer model snflarmzdaki zelliklerden herhangi birini deitirmemiz gerekirse, onlarn factory constructor'larn gncellememiz yeterlidir:
@freezedclass Review with _$Review { factory Review({ // update any properties as needed required double score, String? review, }) = _Review; factory Review.fromJson(Map<String, dynamic> json) => _$ReviewFromJson(json);}
@freezedclass Restaurant with _$Restaurant { factory Restaurant({ // update any properties as needed required String name, required String cuisine, @JsonKey(name: 'year_opened') int? yearOpened, @Default([]) List<Review> reviews, }) = _Restaurant; factory Restaurant.fromJson(Map<String, dynamic> json) => _$RestaurantFromJson(json);}
Ardndan kod oluturucuyu tekrar altrabiliriz ve gerisini Freezed halleder:
flutter pub run build_runner build --delete-conflicting-outputs
Artk birka satrlk kodda gvenli , deimez model snflar tanmlayabilir ve tek bir komut altrarak tm JSON seriletirme kodunu oluturabiliriz.
JSON ek aklamalar
Freezed , kod oluturucunun modellerimizi nasl ilediini zelletirmemize izin veren birok ek aklamay destekler .
En kullanl olanlar @JsonKey
ve @Default
dr
@freezedclass TMDBMovieBasic with _$TMDBMovieBasic { factory TMDBMovieBasic({ @JsonKey(name: 'vote_count') int? voteCount, required int id, @Default(false) bool video, @JsonKey(name: 'vote_average') double? voteAverage, required String title, double? popularity, @JsonKey(name: 'poster_path') required String posterPath, @JsonKey(name: 'original_language') String? originalLanguage, @JsonKey(name: 'original_title') String? originalTitle, @JsonKey(name: 'genre_ids') List<int>? genreIds, @JsonKey(name: 'backdrop_path') String? backdropPath, bool? adult, String? overview, @JsonKey(name: 'release_date') String? releaseDate, }) = _TMDBMovieBasic; factory TMDBMovieBasic.fromJson(Map<String, dynamic> json) => _$TMDBMovieBasicFromJson(json);}
Freezed'e hangi anahtarlarn hangi zelliklerle elendiini sylemek iin @JsonKey
ek aklamasn kullanabiliriz.
Null yaplamayan belirli bir zellik iin varsaylan bir deer belirtmek istiyorsak @Default
ek aklamasn kullanabiliriz.
Kod Oluturma (Code Generation) Dezavantajlar
Kod oluturmann baz ak faydalar vardr ve ok sayda model snfnz varsa, gitmeniz gereken yol budur.
Ama baz dezavantajlar da vardr:
Bir sr ekstra kod
Restaurant ve Review model snflarmz ok basittir, ancak oluturulan kod 450 satr yer kaplar. Bu, ok sayda model snfnz varsa hzla eklenir.
Kod oluturma yavatr
Dart'ta kod oluturma olduka yavatr.
Bunu azaltmann yollar olsa da, codegen (code generation) byk projelerde gelitirme i aknz nemli lde yavalatabilir.
Oluturulan dosyalar git'e eklenmeli mi?
Bir ekipte alyorsanz ve oluturulan dosyalar git'e balyorsanz, ekme isteklerini gzden geirmek zorlar.
Ancak bunu yapmazsanz, proje varsaylan olarak altrlabilir durumda deildir ve:
her ekip yesinin codegen admn altrmay hatrlamas gerekir (potansiyel olarak tutarszlklara yol aar)
uygulamay oluturmak iin zel bir CI oluturma adm gereklidir
Ve oluturulan dosyalarn git'e eklenip eklenmeyecei konusunda henz bir fikir birlii yoktur.
Sonu
JSON seriletirme iin eitli seenekleri aratrdk.
En iyi yaklam semenize yardmc olacak baz ynergeler unlardr:
Birka kk model snfnz varsa, JSON ayrtrma kodunu elle yazabilirsiniz.
Birok model snfnz varsa, Freezed sizin iin heavy-lifting yapabilir.
ileri daha da hzlandrmak iin, VS Code iin Json to Dart Model uzantsn da kullanabilirsiniz.
Original Link: https://dev.to/gulsenkeskin/freezed-kullanarak-flutterda-json-nasil-ayristirilir-10m6
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To