こんにちは。Dartの世界へようこそ。
Dartを深く知れば知るほど、その「静的型付けの厳格さ」と「実行時のパフォーマンス」のバランスの良さに驚かされるはずです。
今日は、Dart開発の登竜門であり、避けては通れない「Null安全(Sound Null Safety)環境下でのJSONシリアライズ」というテーマでお話しします。
APIから受け取るデータは「いつ、どこで、何が欠けるか分からない」不確定な存在です。これをいかにしてDartの堅牢な型システムに適合させるか。ここをマスターすれば、あなたのアプリは劇的にクラッシュしにくくなります。
—
1. なぜJSONパースが「Null安全」の壁になるのか?
DartのNull安全は、「変数はデフォルトでNullにならない」という強力な保証です。しかし、APIから返ってくるJSONデータは、「値が欠けている(null)」状態を平気で送ってきます。
もし、Dartのコードで `String name` と定義しているのに、JSON側に `name: null` があったら? そのまま代入しようとすれば、コンパイル時(または実行時)に Null Safety の壁に激突しますよね。
そこで、我々Dartエンジニアは `freezed` と `json_serializable` という強力な武器を使います。
—
2. 魔法のツール:freezed と json_serializable の役割
これらは単なる「コード生成ツール」ではありません。「実行時(JSON)の不定性」を「コンパイル時(Dart)の型安全性」に変換する翻訳機だと捉えてください。
- `json_serializable`: JSONをDartのオブジェクトに変換する「マッピング」を担当。
- `freezed`: 不変性(Immutable)の保証、`copyWith` メソッド、そして強力な `Union` 型のサポートを担当。
これらを組み合わせることで、「NullableなJSON」を「Non-nullableなDartオブジェクト」へ安全に橋渡しします。
—
3. 実践: Null安全を掌握するデータクラスの設計
まずは、APIレスポンスを受け取るためのクラスを定義してみましょう。
import ‘package:freezed_annotation/freezed_annotation.dart’;
// ファイル名に合わせて生成用ファイルを指定
part ‘user.freezed.dart’;
part ‘user.g.dart’;
@freezed
class User with _$User {
const factory User({
required String id,
// JSONに値がない場合、デフォルト値として空文字を設定
@Default(”) String name,
// Nullableな値は、明示的に `?` をつける
String? email,
}) = _User;
// JSONからの変換処理を自動生成
factory User.fromJson(Map
}
ここがポイント!
- `@Default(”)`: これが重要です。「JSONに `name` キーがない、あるいは `null` が入っている」という状況を、`””` という安全な値に変換してくれます。
- `String?`: `email` のように、本当に値が存在しない可能性がある場合は、正直に `?` を付けましょう。これでDartコンパイラは「この値はNullかもしれない」という警戒信号を発し、使う場所でNullチェックを強制してくれます。
—
4. 初学者が陥りやすい「落とし穴」
多くの人がここで躓くポイントを、先回りして解説しておきますね。
① フィールドの型とJSONの型が一致しない
一番多いのが、「JSONでは `100`(int)が来ているのに、Dart側で `String` と定義してしまう」ケースです。Dart VMは、型不整合を即座に検知し、実行時に `TypeError` を投げます。
対策: API仕様書を信じすぎず、まずは `dynamic` で受けて `print(json.runtimeType)` で確認する癖をつけましょう。
② @Default を過信しない
`@Default` は「JSONにキーそのものがない」または「値がnull」の時に働きます。しかし、JSON側が間違った型を返してきた場合は無力です。外部からのデータは「汚いもの」と仮定し、変換レイヤーで可能な限りバリデーションを行うのがプロの作法です。
—
5. まとめ:型システムを味方につけるために
DartのNull安全は、あなたを縛り付けるための鎖ではありません。「どこでNullをチェックすべきか」をコンパイラが教えてくれる強力なガイドラインです。
1. JSONからの入り口では、必ず `json_serializable` を通す。
2. 存在しない可能性があるデータには `@Default` を使い、デフォルト値を定義する。
3. 本当にNullが必要な時だけ `?` を使う。
この3つを守るだけで、あなたの書くDartコードの信頼性は格段に向上します。
「JSONをパースする」という作業は、外部世界のカオスを、我々が管理する秩序ある型システムへ持ち込む儀式です。コード生成ツールを使いこなし、人間が手作業でNullチェックを書くような不毛な苦労から解放されましょう。
ここをクリアしたあなたは、もうDartの型システムと対話ができるようになっています。次のステップとして、`Either` 型などを使ったより高度なエラーハンドリングにも挑戦してみてください。応援しています!