JSON serialization and deserialization state in dart
I have had good experience with serialization in C # and after searching and testing some Dart libraries, I feel like there is no satisfactory answer overall.
- Id like to know the current state of JSON serialization / deserialization in Dart?
- What should we expect in the future?
- Will this ultimately be supported by the language itself?
- What are the currently best practices?
I'd also like everyone reading this to post any new information even if the post gets old.
source to share
Currently the best option is probably using the Smoke library .
This is a subset of the Mirrors functionality, but has both a mirror-based implementation and Codegen. This is written by the PolymerDart team, so this is close to "Official" as we're going to get it.
It will use Mirrors-based encoding / decoding during development; but for posting, you can create a small transformer that will generate the code.
Seth Ladd created some sample code here that I extended a bit to support child objects:
abstract class Serializable { static fromJson(Type t, Map json) { var typeMirror = reflectType(t); T obj = typeMirror.newInstance(new Symbol(""), const[]).reflectee; json.forEach((k, v) { if (v is Map) { var d = smoke.getDeclaration(t, smoke.nameToSymbol(k)); smoke.write(obj, smoke.nameToSymbol(k), Serializable.fromJson(d.type, v)); } else { smoke.write(obj, smoke.nameToSymbol(k), v); } }); return obj; } Map toJson() { var options = new smoke.QueryOptions(includeProperties: false); var res = smoke.query(runtimeType, options); var map = {}; res.forEach((r) => map[smoke.symbolToName(r.name)] = smoke.read(this, r.name)); return map; } }
There is currently no support for getting type type information (for example, to maintain a list) in Smoke; however I have covered it here:
https://code.google.com/p/dart/issues/detail?id=20584
Until this problem is implemented, a "good" implementation of what you want is not really possible; but I hope this will be implemented soon; because doing something basic like JSON serialization depends on it!
Alan Knight is also working on the Serialization package, however I found it lacked support as easy as converting datetimes to strings, and the solution seemed pretty verbose for something so basic.
Now, in my own project, I went with coding our json serialization (in the form of the toMap and fromMap methods), since we would already have the C # versions of our classes for the server side. Time permitting, I'd like to strip that code and make a NuGet package (it supports nested objects, arrays, excluding properties, etc.).
source to share
Currently, you can use redstone_mapper to transform Dart and JSON objects. This package is a plugin for Redstone.dart , but can be used without it. There are other Pub options available as well
source to share
There is no "one size fits all" serialization solution. For a lengthy discussion see https://groups.google.com/a/dartlang.org/forum/#!searchin/misc/serialization/misc/0pv-Uaq8FGI/5iMrzOrlUKwJ
source to share
Typically, the move from mirrored solutions to codec solutions relies specifically on the source_gen package. This is because codegen can provide less and faster execution times than mirrors.
One package that codegen uses for serialization is built_value:
https://github.com/google/built_value.dart
With built_value, your model classes look like this:
abstract class Account implements Built<Account, AccountBuilder> {
static Serializer<Account> get serializer => _$accountSerializer;
int get id;
String get name;
BuiltMap<String, JsonObject> get keyValues;
factory Account([updates(AccountBuilder b)]) = _$Account;
Account._();
}
Note that built_value isn't just about serialization - it also provides an == operator, hashCode, toString, and a builder class.
source to share
Dart has an implementation for encoding and decoding maps, lists and primitive types. You can find examples at this article . If you are looking for speed this is probably the fastest as they implement json conversion in native C / C ++ - libraries created by the authors are usually written in Dart and will be slower.
The disadvantage JSON.encode
, and JSON.decode
is something that they can not take any other objects, other than those mentioned above, without the methods and toJson fromJson.
Fortunately, there are libraries out there that use reflection in Dart to make it easier. I have created a small library myself to serialize and deserialize objects to and from JSON without additional code for your classes. You can find it here . In addition to the above solutions for your problem, many of them can be found on the Dart pub website .
source to share
I realize this is an old question, but if you come here in 2019+ I found a great code generation solution:
https://pub.dartlang.org/packages/json_serializable
Judging by the git-hub repository, I would say that this is also an "official" solution.
It works using annotations @JsonSerializable
and @JsonKey
to control serialization. In my experience, it seems to handle inheritance and the like flawlessly. It automatically generates serialization and decentralization functions when creating a project.
source to share