flutter-implement-json-serialization
작성자: flutter
Create model classes with `fromJson` and `toJson` methods using `dart:convert`. Use when manually mapping JSON keys to class properties for simple data…
npx skills add https://github.com/flutter/skills --skill flutter-implement-json-serializationSerializing JSON Manually in Flutter
Contents
- Core Guidelines
- Workflow: Implementing a Serializable Model
- Workflow: Fetching and Parsing JSON
- Examples
Core Guidelines
- Import
dart:convert: Utilize Flutter's built-indart:convertlibrary for manual JSON encoding (jsonEncode) and decoding (jsonDecode). - Enforce Type Safety: Always cast the
dynamicresult ofjsonDecode()to the expected type, typicallyMap<String, dynamic>for objects orList<dynamic>for arrays. - Encapsulate Serialization Logic: Define plain model classes containing properties corresponding to the JSON structure. Implement a
fromJsonfactory constructor and atoJsonmethod within the model. - Handle Background Parsing: If parsing large JSON documents (execution time > 16ms), offload the parsing logic to a separate isolate using Flutter's
compute()function to prevent UI jank. - Throw Exceptions on Failure: When handling HTTP responses, throw an exception if the status code is not successful (e.g., not 200 OK or 201 Created). Do not return
null.
Workflow: Implementing a Serializable Model
Use this checklist to implement manual JSON serialization for a data model.
Task Progress:
- Define the plain model class with
finalproperties. - Implement the
factory Model.fromJson(Map<String, dynamic> json)constructor. - Implement the
Map<String, dynamic> toJson()method. - Write unit tests for both serialization methods.
- Run validator -> review type mismatch errors -> fix casting logic.
- Define the Model: Create a class with properties matching the JSON keys.
- Implement
fromJson: Extract values from theMapand cast them to the appropriate Dart types. Use pattern matching or explicit casting. - Implement
toJson: Return aMap<String, dynamic>mapping the class properties back to their JSON string keys. - Validate: Execute unit tests to ensure type safety, autocompletion, and compile-time exception handling function correctly.
Workflow: Fetching and Parsing JSON
Use this conditional workflow when retrieving and parsing JSON from a network request.
Task Progress:
- Execute the HTTP request.
- Validate the response status code.
- Determine parsing strategy (Synchronous vs. Isolate).
- Decode and map the JSON to the model.
- Execute Request: Use the
httppackage to perform the network call. - Validate Response:
- If
response.statusCode == 200(or 201 for POST), proceed to parsing. - If the status code indicates failure, throw an
Exception.
- If
- Determine Parsing Strategy:
- If parsing a small payload (e.g., a single object), parse synchronously on the main thread.
- If parsing a large payload (e.g., an array of thousands of objects), use
compute(parseFunction, response.body)to parse in a background isolate.
- Decode and Map: Pass the decoded JSON to your model's
fromJsonconstructor.
Examples
High-Fidelity Model Implementation
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,
};
}
}
Synchronous Parsing (Small Payload)
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');
}
}
Background Parsing (Large Payload)
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');
}
}
flutter의 다른 스킬
dart-modern-features
flutter
현대화를 위한 후보를 찾으려면:
official
dart-log-failure-parser
flutter
Dart 및 Flutter 테스트 로그에서 실패를 파싱합니다.
official
find-release
flutter
주어진 커밋이 포함된 가장 낮은 Dart 및 Flutter 릴리스를 찾는 스킬입니다. 사용자가 Flutter나 Dart에서 커밋이 언제 포함되었는지 물을 때 이 스킬을 사용하세요…
official
flutter-pr-checks-finder
flutter
Flutter PR에서 실패한 검사를 찾고 해당 LUCI 로그 URL을 찾습니다.
official
rebuilding-flutter-tool
flutter
Flutter 도구와 CLI를 재빌드합니다. 사용자가 Flutter 도구나 CLI를 컴파일, 업데이트, 재생성 또는 재빌드하도록 요청할 때 사용하세요.
official
upgrade-browser
flutter
Flutter Web Engine 및/또는 Framework 테스트에서 브라우저 버전(Chrome 또는 Firefox)을 업그레이드합니다. Chrome 또는 Firefox를 최신 버전으로 롤 또는 업그레이드하라는 요청을 받을 때 사용하세요.
official
create-catalog-item
flutter
사용자가 JSON 스키마 정의를 기반으로 새 CatalogItem, 데이터 클래스 및/또는 위젯 클래스를 생성하도록 요청할 때 이 스킬을 사용하세요.
official
genui-helper
flutter
이 스킬은 genui 저장소에 특화된 워크플로우와 모범 사례를 제공합니다.
official