Flutter開発入門24 FlutterでのJSONシリアライズ:データのやりとりをシンプルにする方法

Flutter

はじめに

 Flutterアプリケーションを開発する際、外部APIとのデータのやりとりでJSON形式がよく使われます。JSONは、データをやりとりする際にシンプルで扱いやすいフォーマットですが、Dartでこのデータを直接操作するのは少し手間がかかります。そこで、Flutterでは、JSONシリアライズ(JSONとDartオブジェクトの相互変換)を効果的に行うためのいくつかの方法が提供されています。本記事では、FlutterでのJSONシリアライズの基本的な使い方を詳しく解説します。

JSONシリアライズとは

 JSONシリアライズとは、DartオブジェクトをJSON形式の文字列に変換するプロセス、もしくはその逆で、JSONデータをDartオブジェクトに変換するプロセスを指します。このプロセスを通じて、APIから取得したデータをDartで扱いやすい形に変換し、また、DartオブジェクトをJSON形式に変換してAPIに送信することができます。

手動でのJSONシリアライズ

 Dartでは、標準ライブラリのdart:convertを使って、JSONデータのエンコード(オブジェクトからJSONに変換)やデコード(JSONからオブジェクトに変換)を行うことができます。

JSONデコード(JSON → Dartオブジェクト)

 外部APIから取得したJSONデータをDartオブジェクトに変換する場合、jsonDecodeを使用します。

import 'dart:convert';

void main() {
  String jsonString = '{"name": "山田", "age": 30}';
  Map<String, dynamic> user = jsonDecode(jsonString);
  print('名前: ${user['name']}, 年齢: ${user['age']}');
}

 この例では、jsonDecodeを使ってJSON形式の文字列をDartのMapに変換しています。APIから取得したデータも同様に扱うことができます。

JSONエンコード(Dartオブジェクト → JSON)

 DartオブジェクトをJSON形式に変換する場合、jsonEncodeを使用します。

import 'dart:convert';

void main() {
  Map<String, dynamic> user = {'name': '山田', 'age': 30};
  String jsonString = jsonEncode(user);
  print(jsonString); // {"name":"山田","age":30}
}

 この例では、jsonEncodeを使ってDartのMapをJSON形式の文字列に変換しています。

クラスを使ったJSONシリアライズ

 APIからのデータを扱う際は、単にMapを使うのではなく、Dartのクラスとしてデータを扱う方が保守性が高まります。クラスを使ってJSONをシリアライズ・デシリアライズする方法を見ていきましょう。

クラスにデコードする

 まずは、APIから取得したJSONデータをクラスに変換する方法です。

import 'dart:convert';

class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      name: json['name'],
      age: json['age'],
    );
  }
}

void main() {
  String jsonString = '{"name": "山田", "age": 30}';
  Map<String, dynamic> userMap = jsonDecode(jsonString);
  User user = User.fromJson(userMap);
  print('名前: ${user.name}, 年齢: ${user.age}');
}

 この例では、Userクラスを定義し、fromJsonファクトリメソッドを使ってJSONデータをクラスインスタンスに変換しています。

クラスをJSONにエンコードする

 次に、Dartオブジェクト(クラス)をJSON形式に変換する方法です。

import 'dart:convert';

class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'age': age,
    };
  }
}

void main() {
  User user = User(name: '山田', age: 30);
  String jsonString = jsonEncode(user.toJson());
  print(jsonString); // {"name":"山田","age":30}
}

 この例では、toJsonメソッドを使ってUserオブジェクトをJSON形式に変換しています。

json_serializableパッケージを使った自動化

 手動でJSONシリアライズを行うと、フィールドが増えるたびに変更が必要になり、ミスが発生しやすくなります。そこで、json_serializableというパッケージを使って、自動的にシリアライズ・デシリアライズを行うコードを生成する方法を紹介します。

パッケージのインストール

dependencies:
  json_annotation: ^4.9.0

dev_dependencies:
  build_runner: ^2.4.12
  json_serializable: ^6.8.0

 次に、以下のコマンドを実行してパッケージをインストールします。

flutter pub get

クラスの定義

 json_serializableを使うと、アノテーションを付けるだけでシリアライズ・デシリアライズが簡単に行えます。

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

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

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

コード生成

 次に、以下のコマンドを実行してコードを自動生成します。

flutter pub run build_runner build

 これにより、user.g.dartというファイルが生成され、Userクラスのシリアライズとデシリアライズに必要なコードが自動で作成されます。以下user.g.dartの例です。

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

User _$UserFromJson(Map<String, dynamic> json) => User(
      name: json['name'] as String,
      age: (json['age'] as num).toInt(),
    );

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

使用例

void main() {
  String jsonString = '{"name": "山田", "age": 30}';
  User user = User.fromJson(jsonDecode(jsonString));
  print('Name: ${user.name}, Age: ${user.age}');

  String encoded = jsonEncode(user.toJson());
  print(encoded); // {"name":""","age":30}
}

 自動生成されたfromJsontoJsonを使って、シンプルにJSONの変換を行うことができます。

まとめ

 FlutterでのJSONシリアライズは、APIとのデータのやりとりを円滑にするための重要なプロセスです。Dartの標準ライブラリを使って手動で行う方法と、json_serializableパッケージを使って自動化する方法の2つを紹介しました。自動化ツールを活用することで、コードの可読性が向上し、開発効率も大幅に上がります。ぜひ、自分のプロジェクトに適した方法でJSONシリアライズを実装してみてください。

コメント