dart-model-from-json について
入力された JSON 構造から、`json_annotation` と `equatable` を使った Dart モデルクラスを生成するスキルです。フィールド型、ネストしたクラス、等価性、シリアライズ方法、出力順を定めています。
主な機能
- 01JSONからDart型へのマッピング
- 02ネストしたオブジェクトクラスの生成
- 03`fromJson` と `toJson` メソッド
- 04`copyWith` と値の等価性
- 05依存順でのクラス出力
活用シーン
- 01APIレスポンスからDartモデルを作成
- 02ネストしたJSONオブジェクトをDartで表現
- 03シリアライズと等価性を備えたモデルを生成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ somnio-software/ somnio-ai-tools --skill dart-model-from-jsonインストール後、Claude Code で/dart-model-from-jsonを入力して読み込まれたか確認します。
詳細
JSON から Dart モデルを生成
json_annotation と equatable を使用して、JSON 構造からDart モデルクラスを生成します。
入力
ユーザーは JSON オブジェクトをコードブロックまたはインラインで貼り付けて提供します。JSON が提供されていない場合は、作業を進める前に JSON の提示を求めてください。
要件
- JSON のシリアライズには
json_annotationを使用します - 値の等価性判定には
equatableを使用します copyWithメソッドを含めますfromJsonメソッドとtoJsonメソッドを含めますequatableのためのpropsゲッターを含めます@immutableデコレーターは使用しません- ドキュメントコメントは付けません
- 明示的に要求されない限り、
@JsonKeyアノテーションは付けません
モデル構造
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'model_name.g.dart';
@JsonSerializable()
class ModelName extends Equatable {
ModelName({
required this.field1,
this.field2,
this.field3 = defaultValue,
});
final String field1;
final int? field2;
final bool field3;
ModelName copyWith({
String? field1,
int? field2,
bool? field3,
}) {
return ModelName(
field1: field1 ?? this.field1,
field2: field2 ?? this.field2,
field3: field3 ?? this.field3,
);
}
static ModelName fromJson(Map<String, dynamic> json) => _$ModelNameFromJson(json);
Map<String, dynamic> toJson() => _$ModelNameToJson(this);
@override
List<Object?> get props => [field1, field2, field3];
}
フィールド型の対応
| JSON 型 | Dart 型 |
|---|---|
string | String |
number(整数) | int |
number(小数) | double |
boolean | bool |
null または欠落 | null 許容型(例:String?) |
プリミティブ型のarray | List<Type> |
オブジェクトのarray | List<ClassName> |
object | 個別のクラス |
命名規則
- クラス名:PascalCase
- フィールド名:camelCase
- 必須フィールド:
requiredキーワードを付けた null 非許容型 - 任意フィールド:
?を付けた null 許容型
ネストされたオブジェクトの規則
個別のクラスを作成する場合
- 複数のプロパティを持つオブジェクトには、必ずクラスを作成します
- オブジェクトを要素に持つ配列には、必ずクラスを作成します
- プリミティブ型の配列には
List<String>、List<int>などを使用します。クラスは不要です
クラス名の推定
| コンテキスト | クラス名 |
|---|---|
address フィールド(オブジェクト) | Address |
profile.preferences(ネストされたオブジェクト) | Preferences |
orders[](オブジェクトの配列) | Order |
orders[].items[](ネストされた配列) | OrderItem |
コンテキストが不明確な場合は、希望するクラス名をユーザーに確認してください。
出力形式
各クラスを、推奨ファイル名を付けた個別のコードブロックとして出力します。
user.dart
// ... User class
address.dart
// ... Address class
必要なクラスを、依存関係の順序(末端のクラスからルートクラスの順)ですべて列挙します。
例
入力 JSON:
{
"id": "123",
"name": "John Doe",
"age": 30,
"isActive": true,
"tags": ["tag1", "tag2"],
"address": {
"street": "123 Main St",
"city": "New York",
"zipCode": "10001"
}
}
出力:
address.dart
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'address.g.dart';
@JsonSerializable()
class Address extends Equatable {
Address({
required this.street,
required this.city,
required this.zipCode,
});
final String street;
final String city;
final String zipCode;
Address copyWith({
String? street,
String? city,
String? zipCode,
}) {
return Address(
street: street ?? this.street,
city: city ?? this.city,
zipCode: zipCode ?? this.zipCode,
);
}
static Address fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
Map<String, dynamic> toJson() => _$AddressToJson(this);
@override
List<Object?> get props => [street, city, zipCode];
}
user.dart
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'address.dart';
part 'user.g.dart';
@JsonSerializable()
class User extends Equatable {
User({
required this.id,
required this.name,
required this.age,
required this.isActive,
required this.tags,
required this.address,
});
final String id;
final String name;
final int age;
final bool isActive;
final List<String> tags;
final Address address;
User copyWith({
String? id,
String? name,
int? age,
bool? isActive,
List<String>? tags,
Address? address,
}) {
return User(
id: id ?? this.id,
name: name ?? this.name,
age: age ?? this.age,
isActive: isActive ?? this.isActive,
tags: tags ?? this.tags,
address: address ?? this.address,
);
}
static User fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
@override
List<Object?> get props => [id, name, age, isActive, tags, address];
}
コメント
Markdown 対応