flutter-implement-json-serialization
`dart:convert` を使用して `fromJson` と `toJson` メソッドを持つモデルクラスを作成します。シンプルなデータ構造に対して、JSONキーをクラスのプロパティに手動でマッピングする際に使用してください。
description の原文を見る
Create model classes with `fromJson` and `toJson` methods using `dart:convert`. Use when manually mapping JSON keys to class properties for simple data structures.
SKILL.md 本文
Flutter での JSON の手動シリアライゼーション
目次
コアガイドライン
dart:convertをインポート: Flutter の組み込みdart:convertライブラリを使用して、JSON エンコード (jsonEncode) とデコード (jsonDecode) を手動で行う。- 型安全性を強制:
jsonDecode()が返すdynamicの結果を常に期待される型(通常はオブジェクトの場合はMap<String, dynamic>、配列の場合はList<dynamic>)にキャストする。 - シリアライゼーションロジックをカプセル化: JSON 構造に対応するプロパティを含むプレーンなモデルクラスを定義する。モデル内に
fromJsonファクトリコンストラクタとtoJsonメソッドを実装する。 - バックグラウンドパースを処理: 大きな JSON ドキュメント(実行時間 > 16ms)をパースする場合は、Flutter の
compute()関数を使用してパースロジックを別の isolate にオフロードして、UI のカクカクを防ぐ。 - 失敗時に例外をスロー: HTTP レスポンスを処理する際、ステータスコードが成功していない場合(例:200 OK や 201 Created ではない)は例外をスローする。
nullを返さない。
ワークフロー: シリアライズ可能なモデルの実装
このチェックリストを使用して、データモデルの手動 JSON シリアライゼーションを実装する。
タスク進行状況:
- プレーンなモデルクラスを
finalプロパティで定義する。 -
factory Model.fromJson(Map<String, dynamic> json)コンストラクタを実装する。 -
Map<String, dynamic> toJson()メソッドを実装する。 - 両方のシリアライゼーションメソッドのユニットテストを書く。
- バリデータを実行 → 型不一致エラーを確認 → キャスティングロジックを修正する。
- モデルを定義: JSON キーに対応するプロパティを持つクラスを作成する。
fromJsonを実装:Mapから値を抽出して適切な Dart 型にキャストする。パターンマッチングまたは明示的なキャストを使用する。toJsonを実装: クラスのプロパティを JSON 文字列キーにマップバックしてMap<String, dynamic>を返す。- バリデート: ユニットテストを実行して、型安全性、自動補完、コンパイル時例外処理が正しく機能することを確認する。
ワークフロー: JSON の取得とパース
ネットワークリクエストから JSON を取得してパースする場合、この条件付きワークフローを使用する。
タスク進行状況:
- HTTP リクエストを実行する。
- レスポンスのステータスコードを検証する。
- パース戦略を決定(同期 vs. Isolate)。
- JSON をデコードしてモデルにマップする。
- リクエストを実行:
httpパッケージを使用してネットワークコールを実行する。 - レスポンスを検証:
response.statusCode == 200(POST の場合は 201)の場合、パースに進む。- ステータスコードがエラーを示す場合、
Exceptionをスローする。
- パース戦略を決定:
- 小さいペイロード(例:単一オブジェクト)をパースする場合、メインスレッドで同期的にパースする。
- 大きいペイロード(例:数千のオブジェクトの配列)をパースする場合、
compute(parseFunction, response.body)を使用してバックグラウンド isolate でパースする。
- デコードしてマップ: デコード済みの JSON をモデルの
fromJsonコンストラクタに渡す。
例
高忠実度モデル実装
import 'dart:convert';
class User {
final int id;
final String name;
final String email;
const User({
required this.id,
required this.name,
required this.email,
});
// Factory constructor for deserialization
factory User.fromJson(Map<String, dynamic> json) {
return switch (json) {
{
'id': int id,
'name': String name,
'email': String email,
} =>
User(
id: id,
name: name,
email: email,
),
_ => throw const FormatException('Failed to load User.'),
};
}
// Method for serialization
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'email': email,
};
}
}
同期パース(小さいペイロード)
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<User> fetchUser(http.Client client, int userId) async {
final response = await client.get(
Uri.parse('https://api.example.com/users/$userId'),
headers: {'Accept': 'application/json'},
);
if (response.statusCode == 200) {
// Decode returns dynamic, cast to Map<String, dynamic>
final Map<String, dynamic> jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
return User.fromJson(jsonMap);
} else {
throw Exception('Failed to load user');
}
}
バックグラウンドパース(大きいペイロード)
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
// Top-level function required for compute()
List<User> parseUsers(String responseBody) {
final parsed = (jsonDecode(responseBody) as List<dynamic>).cast<Map<String, dynamic>>();
return parsed.map<User>((json) => User.fromJson(json)).toList();
}
Future<List<User>> fetchUsers(http.Client client) async {
final response = await client.get(
Uri.parse('https://api.example.com/users'),
headers: {'Accept': 'application/json'},
);
if (response.statusCode == 200) {
// Offload expensive parsing to a background isolate
return compute(parseUsers, response.body);
} else {
throw Exception('Failed to load users');
}
}
ライセンス: BSD-3-Clause(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- flutter
- リポジトリ
- flutter/skills
- ライセンス
- BSD-3-Clause
- 最終更新
- 不明
Source: https://github.com/flutter/skills / ライセンス: BSD-3-Clause
関連スキル
agent-browser
AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。
anyskill
AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。
engram
AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。
skyvern
AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。
pinchbench
PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。
openui
OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。