Рубрики
Flutter

JSON Serialisation во Flutter: jsonSerializable против freezed

Code generation best practices для JSON сериализации во Flutter: сравнение jsonSerializable и freezed пакетов.

Работа с JSON — обязательная часть большинства Flutter приложений. В этой статье сравним два популярных подхода: jsonSerializable и freezed.

Проблема

Flutter не имеет встроенной поддержки JSON. Нужны сторонние пакеты.

json_annotation + json_serializable

Традиционный подход от Dart team.

Установка

dependencies:
  json_annotation: ^4.9.0
dev_dependencies:
  json_serializable: ^6.8.0
  build_runner: ^2.4.0

Использование

import 'package:json_annotation/json_annotation.dart';
import 'package:json_serializable/json_serializable.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  final String id;
  final String name;
  final String email;

  User({
    required this.id,
    required this.name,
    required this.email,
  });

  factory User.fromJson(Map<String, dynamic> json) =>
      _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

Pros

  • Официальное решение
  • Стабильное
  • Хорошая документация

Cons

  • Много boilerplate
  • Дублирование кода

freezed

Современный подход с immutable классами и union types.

Установка

dependencies:
  freezed_annotation: ^2.4.0
dev_dependencies:
  freezed: ^2.5.0
  json_serializable: ^6.8.0
  build_runner: ^2.4.0

Использование

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

part 'user.freezed.dart';
part 'user.g.dart';

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

  factory User.fromJson(Map<String, dynamic> json) =>
      _$UserFromJson(json);
}

Pros

  • Меньше кода
  • Immutable по умолчанию
  • copyWith метод
  • Union types

Cons

  • Ещё одна зависимость
  • Learning curve

freezed + json_serializable

Комбинация для лучшего результата:

@freezed
class User with _$User {
  const factory User({
    required String id,
    required String name,
    @JsonKey(name: 'user_email') required String email,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) =>
      _$UserFromJson(json);
}

Заключение

Для новых проектов рекомендую freezed — он безопаснее и удобнее. json_serializable используйте если хотите минимизировать зависимости.