Flutter Implement Json Serialization Skill Security Audit
What the author says it does (original text)
Create model classes with `fromJson` and `toJson` methods using `dart:convert`. Use when manually mapping JSON keys to class properties for simple data structures.
No obvious risks found in this check
- Files checked
- 1
- Risks found
- 0
Inside this skill
The Skill primarily guides manual Dart model serialization with `fromJson` and `toJson`, requiring explicit type checks on decoded data; mismatched fields cause a format exception rather than being silently accepted.
View source
- **Import `dart:convert`**: Utilize Flutter's built-in `dart:convert` library for manual JSON encoding (`jsonEncode`) and decoding (`jsonDecode`).- **Enforce Type Safety**: Always cast the `dynamic` result of `jsonDecode()` to the expected type, typically `Map<String, dynamic>` for objects or `List<dynamic>` for arrays.- **Encapsulate Serialization Logic**: Define plain model classes containing properties corresponding to the JSON structure. Implement a `fromJson` factory constructor and a `toJson` method 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. // 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.'), };Network access appears in a conditional workflow: it recommends using the `http` package, checking response status, and parsing the response. The supplied requests are examples targeting `api.example.com`; no real service, credentials, upload logic, or concealed data transfer is shown.
View source
## Workflow: Fetching and Parsing JSONUse this conditional workflow when retrieving and parsing JSON from a network request.1. **Execute Request**: Use the `http` package to perform the network call.2. **Validate Response**: - If `response.statusCode == 200` (or 201 for POST), proceed to parsing. - If the status code indicates failure, throw an `Exception`.3. **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.4. **Decode and Map**: Pass the decoded JSON to your model's `fromJson` constructor.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'}, );For large responses, the Skill recommends moving JSON decoding and model mapping to a Flutter background isolate to reduce main-thread jank; the example processes only the supplied response string.
View source
- **Encapsulate Serialization Logic**: Define plain model classes containing properties corresponding to the JSON structure. Implement a `fromJson` factory constructor and a `toJson` method 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`.// 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 {Files and check records1 files
Coverage and gaps
Content covered in each file
These are the source ranges included in this check, not a guarantee that every issue has been resolved.
SKILL.mdFull text included
This report is for the version above. We read the available code and instructions without running the skill or checking extra packages it installs. This is not a promise of safety: a different version or setup may behave differently.
SKILL.mdInstructions
Operations mentioned in code and instructions
Connect to websites
final response = await client.get( Uri.parse('https://api.example.com/users/$userId'), headers: {'Accept': 'application/json'}, final response = await client.get( Uri.parse('https://api.example.com/users'), headers: {'Accept': 'application/json'},- Lines read
- 154
- File checksum (to compare versions)
- 4c9bafec450674912c52cbaa5ba894d8427364f266cba9871ff4916bf73d1a4b