Main featured image

Flutter JsonSerializableでスネークケースのjsonフィールドを自動で変換する

Flutter
Dart

Flutter で API 通信のレスポンスをオブジェクトに変換する便利な package の JsonSerializable の小ネタです。

JsonSerializable を使っていて json フィールドのキー名がスネークケース、変換したいオブジェクトのプロパティ名が同名のキャメルケースの場合があると思います。

{
  "id": 330997542,
  "full_name": "Jasyyie/sympli.search.api",
  "html_url": "https://github.com/Jasyyie",
  "avatar_url": "https://avatars.githubusercontent.com/u/49047008?v=4"
}

API からこんな json レスポンスがあったとしたら、通常 @JsonKey アノテーションを付けてキー名とプロパティ名をマッピングします。

@freezed
abstract class RepositoryEntity with _$RepositoryEntity {
  const factory RepositoryEntity({
    @required final int id,
    @required @JsonKey(name: 'full_name') final String fullName,
    @required @JsonKey(name: 'html_url') final String htmlUrl,
    @required @JsonKey(name: 'avatar_url') final String avatarUrl,
  }) = _RepositoryEntity;

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

このようにクラスのプロパティ数が少ない場合は良いですが、これが何十個もある場合都度 @JsonKey アノテーションをつけるのはミスも発生しやすくオススメしません。

そこで JsonSerializable の build.yaml を設置して @JsonKey のマッピングを自動化しましょう。

環境
  • macOS Big Sur 11.1
  • Android Studio 4.1.2
  • Flutter 1.22.6
  • Dart 2.10.5
設定方法

設定は簡単で、プロジェクトルートの階層に build.yaml を作成して以下コピペします。

元ネタは公式の Build configuration を参照ください。

targets:
  $default:
    builders:
      json_serializable:
        options:
          # Options configure how source code is generated for every
          # `@JsonSerializable`-annotated class in the package.
          #
          # The default value for each is listed.
          any_map: false
          checked: true # false -> true
          create_factory: true
          create_to_json: true
          disallow_unrecognized_keys: false
          explicit_to_json: false
          field_rename: snake # none -> snake
          generic_argument_factories: false
          ignore_unannotated: false
          include_if_null: true

field_renamenone から snake にします。

するとスネークケースのキー名を自動でプロパティにマッピングしてくれます。

今回ついでに checked もデフォルト false から true にしています。

checked パラメータは checked property にある通り、デシリアライズする時プロパティを検査して、型変換に失敗した場合に CheckedFromJsonException を投げてエラー箇所を教えてくれます。

それでは先程のクラスを設定に合わせて書き換えてみましょう。

@freezed
abstract class RepositoryEntity with _$RepositoryEntity {
  const factory RepositoryEntity({
    @required final int id,
    @required final String fullName,
    @required final String htmlUrl,
    @required final String avatarUrl,
  }) = _RepositoryEntity;

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

このように先程のクラスから @JsonKey を書かなくても json からオブジェクトに変換してくれます。

おわりに

今回作成した build.yaml はプロジェクト新規作成時に都度作成するのは面倒、そして作成するのを忘れやすいのです。

以前 Android Studio の Flutter テンプレートをカスタマイズしてプロジェクト新規作成時の設定を自動化する記事を書きました。

Flutter テンプレートで build.yaml を自動で作成するやり方も紹介しているので、ぜひ参考にしてください。

Written by ZUMA a.k.a. Kazuma. Web/Mobile App developer.  My profile.
Tags
Archives
2021-102021-092021-072021-062021-052021-042021-032021-022021-01
Recent Posts