Ce que fait cet outil
Un échantillon JSON devient des classes Dart, chacune avec une fabrique fromJson et une méthode toJson.
{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
class Root {
final int id;
final String firstName;
final Address address;
Root({required this.id, required this.firstName, required this.address});
factory Root.fromJson(Map<String, dynamic> json) => Root(
id: json['id'] as int,
firstName: json['firstName'] as String,
address: Address.fromJson(json['address'] as Map<String, dynamic>),
);
Map<String, dynamic> toJson() => <String, dynamic>{
'id': id,
'firstName': firstName,
'address': address.toJson(),
};
}
Pas de build_runner, pas d’annotations, pas de fichier part engendré : la correspondance est là, sous vos yeux, et vous pouvez la modifier.
La clé ne s’en va jamais
Un nom de champ Dart ne porte pas de tiret et ne commence pas par un chiffre, et class est réservé. Quand un nom doit changer, les deux sens gardent la clé :
final String contentType;
final int class_;
factory Root.fromJson(Map<String, dynamic> json) => Root(
contentType: json['content-type'] as String,
class_: json['class'] as int,
);
Map<String, dynamic> toJson() => <String, dynamic>{
'content-type': contentType,
'class': class_,
};
Comme la correspondance est du code et non une convention, rien n’est deviné à l’exécution — et vous lisez ce qui sera envoyé avant de l’envoyer.
Listes et objets imbriqués
Une liste d’objets devient une classe à part, et la correspondance la parcourt :
items: (json['items'] as List<dynamic>)
.map((e) => ItemsItem.fromJson(e as Map<String, dynamic>))
.toList(),
Une liste de scalaires passe par cast, moins coûteux : (json['tags'] as List<dynamic>).cast<String>().
Ce qu’un échantillon ne peut pas dire
Chaque champ est final et required, et aucun n’est nullable — parce que le document avait une valeur pour chacun. Une clé manquante devient donc un TypeError au décodage, qui nomme le champ, plutôt qu’un null qui voyage trois écrans avant de casser.
Seul un null donne dynamic, qui accepte tout et ne vérifie rien. Une liste vide ou mêlée donne List<dynamic> pour la même raison. Ce sont les trois endroits à revisiter dès que vous avez une seconde charge.
Confidentiel par conception
Tout s’exécute localement dans votre navigateur en JavaScript. Vos données ne sont jamais envoyées sur un serveur, ce qui rend l’outil sûr pour des contenus sensibles, et il fonctionne hors ligne.