DSON is a dart library which converts Dart Objects into their JSON representation.
This library was initially a fork from Dartson. Now it contains some differences:
depth
parameter, which allows users to specify how deep in the object graph they want to serialize.@ignore
over every attribute. This make excluding attributes too global and hardcoded, so users can only specify one exclusion schema.exclude
map as parameter for toJson
method. This is more flexible, since it allows to have many exclusion schemas for serialization.@serializable
instead @entity
which is used by Dartson.Create a new dart project.
Add dependencies to pubspec.yaml
...
dependencies:
...
dson: ^0.5.0
...
tool/watch.dart
and add next code on it:import 'package:build_runner/build_runner.dart';
import 'package:dson/phase.dart';
main() async {
await watch(new PhaseGroup()
..addPhase(
// In next line replace `example/**.dart` for the globs you want to use as input, for example `**/*.dart`
// to take all the dart files of the project as input.
dsonPhase(const ['example/**.dart'])),
deleteFilesByDefault: true);
}
Run tool/watch.dart
to begin watching for changes in dart files
Create/edit bin/main.dart
or web/main.dart
and add the code shown in any of the samples below.
To convert objects to JSON strings you only need to use the toJson
function, annotate the object with @serializable
and pass the object
to the toJson
function as parameter:
library example.object_to_json; // this line is needed for the generator
import 'package:dson/dson.dart';
part 'object_to_json.g.dart'; // this line is needed for the generator
@serializable
class Person extends _$PersonSerializable {
int id;
String firstName;
var lastName; //This is a dynamic attribute could be String, int, double, num, date or another type
double height;
DateTime dateOfBirth;
@SerializedName("renamed")
String otherName;
@ignore
String notVisible;
// private members are never serialized
String _private = "name";
String get doGetter => _private;
}
void main() {
_initMirrors();
Person object = new Person()
..id = 1
..firstName = "Jhon"
..lastName = "Doe"
..height = 1.8
..dateOfBirth = new DateTime(1988, 4, 1, 6, 31)
..otherName = "Juan"
..notVisible = "hallo";
String jsonString = toJson(object);
print(jsonString);
// will print: '{"id":1,"firstName":"Jhon","lastName":"Doe","height":1.8,"dateOfBirth":"1988-04-01T06:31:00.000","renamed":"Juan","doGetter":"name"}'
}
To convert objects to Maps you only need to use the toMap
function, annotate the object with @serializable
and pass the object
to toMap
function as parameter:
library example.object_to_map; // this line is needed for the generator
import 'package:dson/dson.dart';
part 'object_to_map.g.dart'; // this line is needed for the generator
@serializable
class Person extends _$PersonSerializable {
int id;
String firstName;
var lastName; //This is a dynamic attribute could be String, int, duble, num, date or another type
double height;
DateTime dateOfBirth;
@SerializedName("renamed")
String otherName;
@ignore
String notVisible;
// private members are never serialized
String _private = "name";
String get doGetter => _private;
}
void main() {
_initMirrors();
Person object = new Person()
..id = 1
..firstName = "Jhon"
..lastName = "Doe"
..height = 1.8
..dateOfBirth = new DateTime(1988, 4, 1, 6, 31)
..otherName = "Juan"
..notVisible = "hallo";
Map map = toMap(object);
print(map);
// will print: '{id:1, firstName: Jhon, lastName: Doe, height: 1.8, dateOfBirth: 1988-04-01T06:31:00.000, renamed: Juan, doGetter: name}'
}
To serialize objects that contains Cyclical References it would be needed to use the annotation @cyclical
. If this annotation is present and the depth
variable is not set then the non-primitive objects are not going to be parsed and only the id (or hashmap if the object does not contains id) is going to be present. Let's see next example:
library example.serialize_cyclical; // this line is needed for the generator
import 'package:dson/dson.dart';
part 'serialize_cyclical.g.dart'; // this line is needed for the generator
@serializable
@cyclical
class Employee extends _$EmployeeSerializable {
int id;
String firstName;
String lastName;
Address address;
Employee manager;
}
@serializable
@cyclical
class Address extends _$AddressSerializable {
int id;
String street;
String city;
String country;
String postalCode;
Employee owner;
}
void main() {
_initMirrors();
var manager = new Employee()
..id = 1
..firstName = 'Jhon'
..lastName = 'Doe';
manager.address = new Address()
..id = 1
..street = 'some street'
..city = 'Miami'
..country = 'USA'
..owner = manager;
var employee = new Employee()
..id = 2
..firstName = 'Luis'
..lastName = 'Vargas'
..manager = manager;
employee.address = new Address()
..id = 2
..street = 'some street'
..city = 'Miami'
..country = 'USA'
..owner = employee;
print(toJson(employee)); //will print: '{"id":2,"firstName":"Luis","lastName":"Vargas","address":{"id":2},"manager":{"id":1}}'
print(toJson(employee.address)); // will print: '{"id":2,"street":"some street","city":"Miami","country":"USA","owner":{"id":2}}'
// depth is a optional parameter that could be a list that should contains strings or Maps<String, Map>
print(toJson(employee, depth: ['address']));
/* will print:
'{"id":2,"firstName":"Luis","lastName":"Vargas",'
'"address":{"id":2,"street":"some street","city":"Miami","country":"USA","owner":{"id":2}},'
'"manager":{"id":1}}'
*/
print(toJson(employee, depth: [{'manager': ['address']}, 'address']));
/* will print:
'{"id":2,"firstName":"Luis","lastName":"Vargas",'
'"address":{"id":2,"street":"some street","city":"Miami","country":"USA",'
'"owner":{"id":2}},'
'"manager":{"id":1,"firstName":"Jhon","lastName":"Doe",'
'"address":{"id":1,"street":"some street","city":"Miami","country":"USA","owner":{"id":1}}}}');
*/
}
as you can see employee has an address, and the address has an owner of type Employee. If the property id
is not present in the object then it is going to take the hashcode
value from the object as reference. And finally, the depth
parameter passed to serialize function tells serializer how deep you want to go throw the reference. This help us not only to avoid cyclical reference, but to determine what referenced objects should be serialized.
The same applies for lists:
library example.serialize_cyclical_list; // this line is needed for the generator
import 'package:dson/dson.dart';
part 'serialize_cyclical_list.g.dart'; // this line is needed for the generator
@serializable
@cyclical
class Student extends _$StudentSerializable {
int id;
String name;
List<Course> courses;
}
@serializable
@cyclical
class Course extends _$CourseSerializable {
int id;
DateTime beginDate;
List<Student> students;
}
void main() {
// by the moment is needed to initialize the mirrors manually
_initMirrors();
var student1 = new Student()
..id = 1
..name = 'student1',
student2 = new Student()
..id = 2
..name = 'student2',
student3 = new Student()
..id = 3
..name = 'student3',
course1 = new Course()
..id = 1
..beginDate = new DateTime.utc(2015, 1, 1)
..students = [student1, student2],
course2 = new Course()
..id = 2
..beginDate = new DateTime.utc(2015, 1, 2)
..students = [student2, student3],
course3 = new Course()
..id = 3
..beginDate = new DateTime.utc(2015, 1, 3)
..students = [student1, student3];
student1.courses = [course1, course3];
student2.courses = [course1, course2];
student3.courses = [course2, course3];
var students = [student1, student2, student3];
print(toJson(students));
print(toJson(student1)); // will print: '{"id":1,"name":"student1","courses":[{"id":1},{"id":3}]}'
print(toJson(student1, depth: ['courses']));
/* will print:
'{'
'"id":1,'
'"name":"student1",'
'"courses":['
'{"id":1,"beginDate":"2015-01-01T00:00:00.000Z","students":[{"id":1},{"id":2}]},'
'{"id":3,"beginDate":"2015-01-03T00:00:00.000Z","students":[{"id":1},{"id":3}]}'
']'
'}');
*/
print(toJson(student1.courses));
/* will print:
'['
'{"id":1,"beginDate":"2015-01-01T00:00:00.000Z","students":[{"id":1},{"id":2}]},'
'{"id":3,"beginDate":"2015-01-03T00:00:00.000Z","students":[{"id":1},{"id":3}]}'
']');
*/
print(toJson(student2.courses, depth: ['students']));
/* will print:
'['
'{"id":1,"beginDate":"2015-01-01T00:00:00.000Z","students":['
'{"id":1,"name":"student1","courses":[{"id":1},{"id":3}]},'
'{"id":2,"name":"student2","courses":[{"id":1},{"id":2}]}'
']},'
'{"id":2,"beginDate":"2015-01-02T00:00:00.000Z","students":['
'{"id":2,"name":"student2","courses":[{"id":1},{"id":2}]},'
'{"id":3,"name":"student3","courses":[{"id":2},{"id":3}]}'
']}'
']'
*/
}
Without the annotation @cyclical
the program is going to throw a stack overflow error caused by the serializing of cyclical objects.
To exclude parameter from being serialized we have two options the first option is using @ignore
over the attribute to ignore. However this approach is too global. What I want to say with this is that the attribute is going to be ignored always.
Another way to exclude attributes is adding the parameter exclude
to serialize
function. In this way we only exclude those attributes during that serialization.
library example.exclude_attributes; // this line is needed for the generator
import 'package:dson/dson.dart';
// replace `main` for the name of your file
part 'exclude_attributes.g.dart'; // this line is needed for the generator
@serializable
@cyclical
class Student extends _$StudentSerializable {
int id;
String name;
List<Course> courses;
}
@serializable
@cyclical
class Course extends _$CourseSerializable {
int id;
DateTime beginDate;
List<Student> students;
}
void main() {
_initMirrors();
var student1 = new Student()
..id = 1
..name = 'student1',
student2 = new Student()
..id = 2
..name = 'student2',
student3 = new Student()
..id = 3
..name = 'student3',
course1 = new Course()
..id = 1
..beginDate = new DateTime.utc(2015, 1, 1)
..students = [student1, student2],
course2 = new Course()
..id = 2
..beginDate = new DateTime.utc(2015, 1, 2)
..students = [student2, student3],
course3 = new Course()
..id = 3
..beginDate = new DateTime.utc(2015, 1, 3)
..students = [student1, student3];
student1.courses = [course1, course3];
student2.courses = [course1, course2];
student3.courses = [course2, course3];
var students = [student1, student2, student3];
print(toJson(students));
/*
will print:
'['
'{"id":1,"name":"student1","courses":[{"id":1},{"id":3}]},'
'{"id":2,"name":"student2","courses":[{"id":1},{"id":2}]},'
'{"id":3,"name":"student3","courses":[{"id":2},{"id":3}]}'
']'
*/
print(toJson(student1)); // will print: '{"id":1,"name":"student1","courses":[{"id":1},{"id":3}]}'
print(toJson(student1, depth: 'courses', exclude: 'name'));
/* will print:
'{'
'"id":1,'
'"courses":['
'{"id":1,"beginDate":"2015-01-01T00:00:00.000Z","students":[{"id":1},{"id":2}]},'
'{"id":3,"beginDate":"2015-01-03T00:00:00.000Z","students":[{"id":1},{"id":3}]}'
']'
'}');
*/
print(toJson(student1.courses, exclude: 'beginDate'));
/* will print:
'['
'{"id":1,"students":[{"id":1},{"id":2}]},'
'{"id":3,"students":[{"id":1},{"id":3}]}'
']');
*/
print(toJson(student2.courses, depth: 'students', exclude: {'students': 'name'}));
/* will print:
'['
'{"id":1,"beginDate":"2015-01-01T00:00:00.000Z","students":['
'{"id":1,"courses":[{"id":1},{"id":3}]},'
'{"id":2,"courses":[{"id":1},{"id":2}]}'
']},'
'{"id":2,"beginDate":"2015-01-02T00:00:00.000Z","students":['
'{"id":2,"courses":[{"id":1},{"id":2}]},'
'{"id":3,"courses":[{"id":2},{"id":3}]}'
']}'
']'
*/
print(toJson(student2.courses, depth: 'students', exclude: ['beginDate', {'students': 'name'}]));
/* will print:
'['
'{"id":1,"students":['
'{"id":1,"courses":[{"id":1},{"id":3}]},'
'{"id":2,"courses":[{"id":1},{"id":2}]}'
']},'
'{"id":2,"students":['
'{"id":2,"name":"student2","courses":[{"id":1},{"id":2}]},'
'{"id":3,"name":"student3","courses":[{"id":2},{"id":3}]}'
']}'
']'
*/
}
To convert JSON strings to objects you only need to use the fromJson
and fromJsonList
functions and pass the json
string to deserialize and the Type
of the object as parameters:
// replace `example` for the name you want to give to your library
library example.json_to_object; // this line is needed for the generator
import 'package:dson/dson.dart';
// replace `main` for the name of your file
part 'json_to_object.g.dart'; // this line is needed for the generator
@serializable
class EntityClass extends _$EntityClassSerializable {
String name;
String _setted;
@SerializedName("renamed")
bool otherName;
@ignore
String notVisible;
List<EntityClass> children;
set setted(String s) => _setted = s;
String get setted => _setted;
}
void main() {
// by the moment is needed to initialize the mirrors manually
_initMirrors();
EntityClass object = fromJson('{"name":"test","renamed":true,"notVisible":"it is", "setted": "awesome"}', EntityClass);
print(object.name); // > test
print(object.otherName); // > blub
print(object.notVisible); // > it is
print(object.setted); // > awesome
// to deserialize a list of items use [fromJsonList]
List<EntityClass> list = fromJson('[{"name":"test", "children": [{"name":"child1"},{"name":"child2"}]},{"name":"test2"}]', [List, EntityClass]);
print(list.length); // > 2
print(list[0].name); // > test
print(list[0].children[0].name); // > child1
}
Maps
and Lists<Map>
to dart objectsFrameworks like Angular.dart come with several HTTP services which already transform the HTTP response to a map using JSON.encode
. To use those encoded Maps or Lists use fromMap
and fromMapList
functions.
library example.map_to_object; // this line is needed for the generator
import 'package:dson/dson.dart';
// replace `main` for the name of your file
part 'map_to_object.g.dart'; // this line is needed for the generator
@serializable
class EntityClass extends _$EntityClassSerializable {
String name;
String _setted;
@SerializedName("renamed")
bool otherName;
@ignore
String notVisible;
List<EntityClass> children;
set setted(String s) => _setted = s;
String get setted => _setted;
}
void main() {
_initMirrors();
EntityClass object = fromMap({
"name": "test",
"renamed": "blub",
"notVisible": "it is",
"setted": "awesome"
}, EntityClass);
print(object.name); // > test
print(object.otherName); // > blub
print(object.notVisible); // > it is
print(object.setted); // > awesome
// to deserialize a list of items use [fromJsonList]
List<EntityClass> list = fromMapList([
{"name": "test",
"children": [
{"name": "child1"},
{"name": "child2"}
]
},
{"name": "test2"}
], EntityClass);
print(list.length); // > 2
print(list[0].name); // > test
print(list[0].children[0].name); // > child1
}
packageName
parameter from phase
and make globs
parameter optionalserializable
to version ^0.3.0
serializable
_initClassMirrors
to _initMirrors
serializable
and built_mirrors
BuiltMirrorsGenerator
to ClassMirrorsGenerator
InitClassMirrorsGenerator
to phase.dart
DsonGenerator
and dsonPhase
var
typesSet
deserializerdouble
on deserializer._convertValue
if (valueType is DynamicMirrorImpl)
to deserializer._convertValue
to convert var
or dynamic
attributesserialize
to toJson
deserialize
to fromJson
deserializeList
to fromJsonList
deserializeMap
to fromJsonMap
objectToSerializable
remains with the same nametoMap
method was createdmap
to fromMap
mapList
to fromMapList
@cyclical
and depth
parameter to avoid cyclical reference errors and determine how deep the user wants to serialize the object.Add this to your package's pubspec.yaml file:
dependencies:
dson: "^0.6.0"
You can install packages from the command line:
with pub:
$ pub get
with Flutter:
$ flutter packages get
Alternatively, your editor might support pub get
or packages get
.
Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:dson/dson.dart';
Version | Uploaded | Documentation | Archive |
---|---|---|---|
0.13.2 | Apr 3, 2018 |
|
|
0.13.1+1 | Apr 3, 2018 |
|
|
0.13.1 | Apr 3, 2018 |
|
|
0.13.0 | Feb 14, 2018 |
|
|
0.12.0 | Feb 7, 2018 |
|
|
0.11.0 | Dec 4, 2017 |
|
|
0.10.2 | Nov 20, 2017 |
|
|
0.10.1 | Nov 20, 2017 |
|
|
0.10.0 | Sep 20, 2017 |
|
|
0.9.1 | Sep 7, 2017 |
|
|
We analyzed this package on Apr 24, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:
Popularity:
Describes how popular the package is relative to other packages.
[more]
|
88 | / 100 |
Health:
Code health derived from static analysis.
[more]
|
98 | / 100 |
Maintenance:
Reflects how tidy and up-to-date the package is.
[more]
|
100 | / 100 |
Overall score:
Weighted score of the above.
[more]
|
93 |
Detected platforms: Flutter, web, other
No platform restriction found in primary library
package:dson/dson.dart
.
The description is too short.
Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.
Package is pre-v1 release.
While there is nothing inherently wrong with versions of
0.*.*
, it usually means that the author is still experimenting with the general direction API.
Fix analysis and formatting issues.
Analysis or formatting checks reported 10 hints.
Run
dartfmt
to formatlib/dson.dart
.Run
dartfmt
to formatlib/generator.dart
.Similar analysis of the following files failed:
lib/phase.dart
(hint)lib/src/annotations.dart
(hint)lib/src/deserializer.dart
(hint)lib/src/exceptions.dart
(hint)lib/src/serializer.dart
(hint)
Maintain an example.
None of the files in your
example/
directory matches a known example patterns. Common file name patterns include:main.dart
,example.dart
or you could also usedson.dart
.
Use analysis_options.yaml
.
Rename old
.analysis_options
file toanalysis_options.yaml
.
Package | Constraint | Resolved | Available |
---|---|---|---|
Direct dependencies | |||
Dart SDK | >=1.8.0 | ||
serializable | ^0.3.0 | 0.3.3 | 0.9.2 |
Transitive dependencies | |||
analyzer | 0.30.0+4 | 0.31.1 | |
args | 1.4.2 | ||
async | 1.13.3 | 2.0.6 | |
barback | 0.15.2+16 | ||
build | 0.9.3 | 0.12.2 | |
build_barback | 0.3.0 | 0.5.0+3 | |
build_runner | 0.3.4+1 | 0.8.3 | |
built_mirrors | 0.2.4 | 0.8.4 | |
charcode | 1.1.1 | ||
cli_util | 0.1.2+1 | ||
code_transformers | 0.5.1+4 | ||
collection | 1.14.9 | ||
convert | 2.0.1 | ||
crypto | 2.0.2+1 | ||
csslib | 0.14.1 | ||
dart_style | 1.0.9+1 | 1.0.10 | |
front_end | 0.1.0-alpha.4.1 | 0.1.0-alpha.11 | |
glob | 1.1.5 | ||
html | 0.13.3 | ||
http_parser | 3.1.1 | ||
isolate | 1.1.0 | 2.0.0 | |
kernel | 0.3.0-alpha.1.1 | 0.3.0-alpha.11 | |
logging | 0.11.3+1 | ||
meta | 1.1.2 | ||
mime | 0.9.6 | ||
package_config | 1.0.3 | ||
path | 1.5.1 | ||
plugin | 0.2.0+2 | ||
pool | 1.3.4 | ||
shelf | 0.6.8 | 0.7.2 | |
shelf_static | 0.2.7 | ||
source_gen | 0.5.10+1 | 0.8.1 | |
source_maps | 0.10.4 | ||
source_span | 1.4.0 | ||
stack_trace | 1.9.2 | ||
stream_channel | 1.6.5 | ||
stream_transform | 0.0.11 | ||
string_scanner | 1.0.2 | ||
typed_data | 1.1.5 | ||
utf | 0.9.0+4 | ||
watcher | 0.9.7+7 | ||
yaml | 2.1.13 | ||
Dev dependencies | |||
test | ^0.12.0 |