flutter-http-and-json — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited flutter-http-and-json (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
strictly required for debugging, configure network_security_config.xml (Android) and NSAppTransportSecurity (iOS).
Uri.https(authority, unencodedPath, [queryParameters]) to safely build URLs. Thishandles encoding and formatting reliably, preventing string concatenation errors.
http.Response.statusCode. Treat 200 (OK) and 201 (Created) as success.Throw explicit exceptions for other codes (do not return null).
compute()function.
system prompt and setting the response MIME type to application/json.
Use this workflow to implement network requests using the http package.
Task Progress:
http package to pubspec.yaml.AndroidManifest.xml and macOS .entitlements).Uri.Conditional Implementation:
http.get(uri).http.post(uri, headers: {...}, body: jsonEncode(data)). Ensure Content-Type isapplication/json; charset=UTF-8.
http.put(uri, headers: {...}, body: jsonEncode(data)).http.delete(uri, headers: {...}).Feedback Loop: Validation & Error Handling
response.statusCode.200 or 201, call jsonDecode(response.body) and map to a Dart object.Exception('Failed to load/update/delete resource').Choose the serialization strategy based on project complexity.
Conditional Implementation:
json_serializable (or Freezed, which wraps it) forimmutable models. This is the recommended path because the generator keeps fromJson, toJson, and equality in sync as fields change.
dart:convert solely for a trivial, throwaway model in a quickprototype. Promote it to json_serializable the moment the model is kept or grows nested fields.
#### Manual Serialization Setup Task Progress:
dart:convert.final properties.factory Model.fromJson(Map<String, dynamic> json) constructor.Map<String, dynamic> toJson() method.#### Code Generation Setup (json_serializable) Task Progress:
flutter pub add json_annotation and flutter pub add -d build_runner json_serializable.json_annotation.dart in the model file.part 'model_name.g.dart'; directive.@JsonSerializable(). Use explicitToJson: true if the class contains nested models.fromJson factory and toJson method delegating to the generated functions.dart run build_runner build --delete-conflicting-outputs.Use this workflow to prevent frame drops when parsing large JSON payloads (e.g., lists of 1000+ items).
Task Progress:
String (the response body) and returns the parsed Dart object(e.g., List<Model>).
jsonDecode and map the results to the Model class.response.body to Flutter's compute()function.
#### Example 1: HTTP GET with Manual Serialization (escape hatch only)
This hand-written model is the throwaway-prototype escape hatch. For any model you keep, generate it with json_serializable or Freezed (Example 4) instead of writing fromJson by hand.
import 'dart:convert';
import 'package:http/http.dart' as http;
class Album {
final int id;
final String title;
const Album({required this.id, required this.title});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
id: json['id'] as int,
title: json['title'] as String,
);
}
}
Future<Album> fetchAlbum() async {
final uri = Uri.https('jsonplaceholder.typicode.com', '/albums/1');
final response = await http.get(uri);
if (response.statusCode == 200) {
return Album.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to load album');
}
}#### Example 2: HTTP POST Request
Future<Album> createAlbum(String title) async {
final uri = Uri.https('jsonplaceholder.typicode.com', '/albums');
final response = await http.post(
uri,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{'title': title}),
);
if (response.statusCode == 201) {
return Album.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to create album.');
}
}#### Example 3: Background Parsing with compute
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
// 1. Top-level function for parsing
List<Photo> parsePhotos(String responseBody) {
final parsed = (jsonDecode(responseBody) as List<Object?>)
.cast<Map<String, Object?>>();
return parsed.map<Photo>(Photo.fromJson).toList();
}
// 2. Fetch function using compute
Future<List<Photo>> fetchPhotos(http.Client client) async {
final uri = Uri.https('jsonplaceholder.typicode.com', '/photos');
final response = await client.get(uri);
if (response.statusCode == 200) {
// Run parsePhotos in a separate isolate
return compute(parsePhotos, response.body);
} else {
throw Exception('Failed to load photos');
}
}#### Example 4: Code Generation (json_serializable)
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(explicitToJson: true)
class User {
final String name;
// Store and transmit timestamps in UTC; render in local time only at the UI
// edge. registrationDateMillis is epoch milliseconds in UTC.
@JsonKey(name: 'registration_date_millis')
final int registrationDateMillis;
User(this.name, this.registrationDateMillis);
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.