Сериализация и десериализация JSON в flutter для больших проектов

06.12.2018 at 08:14

В прошлой статье я рассказывал о получении JSON по HTTP и десериализации ответа. Парсинг JSON был сделан вручную. Такой вариант подходит для маленьких проектов, разрабатываемых в одиночку, но вызовет множество проблем в более крупном проекте.

Для крупных проектов разбор JSON лучше генерировать. Используется для этого пакет json_serializable.

В файле pubspec.yaml в секцию dependencies добавляем

json_annotation: ^2.0.0

А в секцию dev_dependencies

build_runner: ^1.0.0
json_serializable: ^2.0.0

dev_dependencies — это зависимости, которые используются в процессе разработки но не используются в production коде. В нашем случае это пакеты, отвечающие за генерацию кода.

Модифицируем класс из прошлой статьи

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  final int id;
  @JsonKey(name: "name")
  final String userName;
  final String email;

  User({this.id, this.userName, this.email});

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

  Map<String, dynamic> toJson() => _$UserToJson(this);
}

Рассмотрим внимательнее изменения.

part 'user.g.dart';

Эта строка нужна для того, чтобы в файле user.dart были видны приватные функции из файла user.g.dart. user.g.dart — это генерируемый файл.

@JsonSerializable()

Эта аннотация указывает, что для этого класса нужно генерировать код.

@JsonKey(name: "name")
final String userName;

Эта аннотация указывает, что свойство userName нужно заполнять из поля name в JSON

Теперь осталось запустить генератор командой

flutter packages pub run build_runner build

Генератор создает файл user.g.dart с двумя функциями:

User _$UserFromJson(Map<String, dynamic> json) {
  return User(
    id: json['id'] as int,
    userName: json['name'] as String,
    email: json['email'] as String);
}

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
  'id': instance.id,
  'name': instance.userName,
  'email': instance.email
};

Это как раз те функции, которые мы используем в классе User.