Skip to content

Commit 4db27a8

Browse files
authored
Big documentation updates/improvements (#1003)
1 parent 4d7a7b0 commit 4db27a8

File tree

9 files changed

+386
-395
lines changed

9 files changed

+386
-395
lines changed

json_serializable/README.md

Lines changed: 115 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ The builders generate code when they find members annotated with classes defined
77
in [package:json_annotation].
88

99
- To generate to/from JSON code for a class, annotate it with
10-
`@JsonSerializable`. You can provide arguments to `JsonSerializable` to
10+
[`JsonSerializable`]. You can provide arguments to [`JsonSerializable`] to
1111
configure the generated code. You can also customize individual fields by
12-
annotating them with `@JsonKey` and providing custom arguments. See the table
13-
below for details on the [annotation values](#annotation-values).
12+
annotating them with [`JsonKey`] and providing custom arguments. See the
13+
table below for details on the [annotation values](#annotation-values).
1414

1515
- To generate a Dart field with the contents of a file containing JSON, use the
16-
`JsonLiteral` annotation.
16+
[`JsonLiteral`] annotation.
1717

1818
## Setup
1919

@@ -23,7 +23,7 @@ To configure your project for the latest released version of,
2323
## Example
2424

2525
Given a library `example.dart` with an `Person` class annotated with
26-
`@JsonSerializable()`:
26+
[`JsonSerializable`]:
2727

2828
```dart
2929
import 'package:json_annotation/json_annotation.dart';
@@ -32,11 +32,20 @@ part 'example.g.dart';
3232
3333
@JsonSerializable()
3434
class Person {
35-
final String firstName;
36-
final String lastName;
35+
/// The generated code assumes these values exist in JSON.
36+
final String firstName, lastName;
37+
38+
/// The generated code below handles if the corresponding JSON value doesn't
39+
/// exist or is empty.
3740
final DateTime? dateOfBirth;
41+
3842
Person({required this.firstName, required this.lastName, this.dateOfBirth});
43+
44+
/// Connect the generated [_$PersonFromJson] function to the `fromJson`
45+
/// factory.
3946
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
47+
48+
/// Connect the generated [_$PersonToJson] function to the `toJson` method.
4049
Map<String, dynamic> toJson() => _$PersonToJson(this);
4150
}
4251
```
@@ -66,74 +75,91 @@ Map<String, dynamic> _$PersonToJson(Person instance) => <String, dynamic>{
6675
Once you have added the annotations to your code you then need to run the code
6776
generator to generate the missing `.g.dart` generated dart files.
6877

69-
With a Dart package, run `pub run build_runner build` in the package directory.
78+
With a Dart package, run `dart run build_runner build` in the package directory.
7079

7180
With a Flutter package, run `flutter pub run build_runner build` in your package
7281
directory.
7382

7483
# Annotation values
7584

76-
The only annotation required to use this package is `@JsonSerializable`. When
85+
The only annotation required to use this package is [`JsonSerializable`]. When
7786
applied to a class (in a correctly configured package), `toJson` and `fromJson`
7887
code will be generated when you build. There are three ways to control how code
7988
is generated:
8089

81-
1. Set properties on `@JsonSerializable`.
82-
2. Add a `@JsonKey` annotation to a field and set properties there.
83-
3. Add configuration to `build.yaml`[see below](#build-configuration).
84-
85-
| `build.yaml` key | JsonSerializable | JsonKey |
86-
| -------------------------- | ------------------------------------------- | --------------------------- |
87-
| any_map | [JsonSerializable.anyMap] | |
88-
| checked | [JsonSerializable.checked] | |
89-
| constructor | [JsonSerializable.constructor] | |
90-
| create_factory | [JsonSerializable.createFactory] | |
91-
| create_to_json | [JsonSerializable.createToJson] | |
92-
| disallow_unrecognized_keys | [JsonSerializable.disallowUnrecognizedKeys] | |
93-
| explicit_to_json | [JsonSerializable.explicitToJson] | |
94-
| field_rename | [JsonSerializable.fieldRename] | |
95-
| generic_argument_factories | [JsonSerializable.genericArgumentFactories] | |
96-
| ignore_unannotated | [JsonSerializable.ignoreUnannotated] | |
97-
| include_if_null | [JsonSerializable.includeIfNull] | [JsonKey.includeIfNull] |
98-
| | | [JsonKey.defaultValue] |
99-
| | | [JsonKey.disallowNullValue] |
100-
| | | [JsonKey.fromJson] |
101-
| | | [JsonKey.ignore] |
102-
| | | [JsonKey.name] |
103-
| | | [JsonKey.required] |
104-
| | | [JsonKey.toJson] |
105-
| | | [JsonKey.unknownEnumValue] |
106-
107-
[JsonSerializable.anyMap]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/anyMap.html
108-
[JsonSerializable.checked]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/checked.html
109-
[JsonSerializable.constructor]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/constructor.html
110-
[JsonSerializable.createFactory]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/createFactory.html
111-
[JsonSerializable.createToJson]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/createToJson.html
112-
[JsonSerializable.disallowUnrecognizedKeys]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/disallowUnrecognizedKeys.html
113-
[JsonSerializable.explicitToJson]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/explicitToJson.html
114-
[JsonSerializable.fieldRename]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/fieldRename.html
115-
[JsonSerializable.genericArgumentFactories]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/genericArgumentFactories.html
116-
[JsonSerializable.ignoreUnannotated]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/ignoreUnannotated.html
117-
[JsonSerializable.includeIfNull]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/includeIfNull.html
118-
[JsonKey.includeIfNull]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/includeIfNull.html
119-
[JsonKey.defaultValue]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/defaultValue.html
120-
[JsonKey.disallowNullValue]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/disallowNullValue.html
121-
[JsonKey.fromJson]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
122-
[JsonKey.ignore]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/ignore.html
123-
[JsonKey.name]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/name.html
124-
[JsonKey.required]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/required.html
125-
[JsonKey.toJson]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html
126-
[JsonKey.unknownEnumValue]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/unknownEnumValue.html
127-
128-
> Note: every `JsonSerializable` field is configurable via `build.yaml` – see
129-
> the table for the corresponding key. If you find you want all or most of your
130-
> classes with the same configuration, it may be easier to specify values once
131-
> in the YAML file. Values set explicitly on `@JsonSerializable` take precedence
132-
> over settings in `build.yaml`.
133-
134-
> Note: There is some overlap between fields on `JsonKey` and
135-
> `JsonSerializable`. In these cases, if a value is set explicitly via `JsonKey`
136-
> it will take precedence over any value set on `JsonSerializable`.
90+
1. Setting properties on [`JsonKey`] annotating the target field.
91+
1. Set properties on [`JsonSerializable`] annotating the target type.
92+
1. Add configuration to `build.yaml`[see below](#build-configuration).
93+
94+
Every [`JsonSerializable`] field is configurable via `build.yaml`. If you find
95+
you want all or most of your classes with the same configuration, it may be
96+
easier to specify values once in the YAML file. Values set explicitly on
97+
[`JsonSerializable`] take precedence over settings in `build.yaml`.
98+
99+
There is some overlap between settings on [`JsonKey`] and
100+
[`JsonSerializable`]. In these cases, the property on [`JsonKey`] takes
101+
precedence over any value set on [`JsonSerializable`].
102+
103+
<!-- TODO: add an example! -->
104+
105+
## Enums
106+
107+
Annotate `enum` types with [`JsonEnum`] (new in `json_annotation` 4.2.0) to:
108+
109+
1. Specify the default rename logic for each enum value using `fieldRename`. For
110+
instance, use `fieldRename: FieldRename.kebab` to encode `enum` value
111+
`noGood` as `"no-good"`.
112+
1. Force the generation of the `enum` helpers, even if the `enum` is not
113+
referenced in code. This is an edge scenario, but useful for some.
114+
115+
Annotate `enum` values with [`JsonValue`] to specify the encoded value to map
116+
to target `enum` entries. Values can be of type [`String`] or [`int`].
117+
118+
<!-- TODO: hoist out to source code! -->
119+
120+
```dart
121+
enum StatusCode {
122+
@JsonValue(200)
123+
success,
124+
@JsonValue('500')
125+
weird,
126+
}
127+
```
128+
129+
# Supported types
130+
131+
Out of the box, `json_serializable` supports many common types in the
132+
[dart:core](https://api.dart.dev/stable/dart-core/dart-core-library.html)
133+
library:
134+
[`BigInt`], [`bool`], [`DateTime`], [`double`], [`Duration`], [`Enum`], [`int`],
135+
[`Iterable`], [`List`], [`Map`], [`num`], [`Object`], [`Set`], [`String`],
136+
[`Uri`]
137+
138+
The collection types –
139+
[`Iterable`], [`List`], [`Map`], [`Set`]
140+
– can contain values of all the above types.
141+
142+
For [`Map`], the key value must be one of
143+
[`BigInt`], [`DateTime`], [`dynamic`], [`Enum`], [`int`], [`Object`],
144+
[`String`], [`Uri`]
145+
146+
# Custom types and custom encoding
147+
148+
If you want to use types that are not supported out-of-the-box or if you want to
149+
customize the encoding/decoding of any type, you have a few options.
150+
151+
1. If you own/cotrol the desired type, add a `fromJson` constructor and/or a
152+
`toJson()` function to the type. Note: while you can use `json_serializable`
153+
for these types, you don't have to! The generator code only looks for these
154+
methods. It doesn't care how they were created.
155+
1. Use the [`JsonKey.toJson`] and [`JsonKey.fromJson`] properties to specify
156+
custom conversions on the annotated field. The functions specified must be
157+
top-level or static. See the documentation of these properties for details.
158+
1. Create an implementation of [`JsonConverter`] and annotate either the
159+
corresponding field or the containing class. [`JsonConverter`] is convenient
160+
if you want to use the same conversion logic on many fields. It also allows
161+
you to support a type within collections. Check out
162+
[these examples](https://github.com/google/json_serializable.dart/blob/master/example/lib/json_converter_example.dart).
137163

138164
# Build configuration
139165

@@ -166,3 +192,27 @@ targets:
166192
[example]: https://github.com/google/json_serializable.dart/tree/master/example
167193
[dart build system]: https://github.com/dart-lang/build
168194
[package:json_annotation]: https://pub.dev/packages/json_annotation
195+
[`BigInt`]: https://api.dart.dev/stable/dart-core/BigInt-class.html
196+
[`bool`]: https://api.dart.dev/stable/dart-core/bool-class.html
197+
[`DateTime`]: https://api.dart.dev/stable/dart-core/DateTime-class.html
198+
[`double`]: https://api.dart.dev/stable/dart-core/double-class.html
199+
[`Duration`]: https://api.dart.dev/stable/dart-core/Duration-class.html
200+
[`dynamic`]: https://api.dart.dev/stable/dart-core/dynamic-class.html
201+
[`Enum`]: https://api.dart.dev/stable/dart-core/Enum-class.html
202+
[`int`]: https://api.dart.dev/stable/dart-core/int-class.html
203+
[`Iterable`]: https://api.dart.dev/stable/dart-core/Iterable-class.html
204+
[`JsonConverter`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html
205+
[`JsonEnum`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum-class.html
206+
[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
207+
[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html
208+
[`JsonKey`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey-class.html
209+
[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonLiteral-class.html
210+
[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html
211+
[`JsonValue`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonValue-class.html
212+
[`List`]: https://api.dart.dev/stable/dart-core/List-class.html
213+
[`Map`]: https://api.dart.dev/stable/dart-core/Map-class.html
214+
[`num`]: https://api.dart.dev/stable/dart-core/num-class.html
215+
[`Object`]: https://api.dart.dev/stable/dart-core/Object-class.html
216+
[`Set`]: https://api.dart.dev/stable/dart-core/Set-class.html
217+
[`String`]: https://api.dart.dev/stable/dart-core/String-class.html
218+
[`Uri`]: https://api.dart.dev/stable/dart-core/Uri-class.html

json_serializable/build.yaml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,10 @@ builders:
9292
build_to: source
9393
runs_before: ["json_serializable"]
9494

95-
_api_table_builder:
96-
import: "tool/api_table_builder.dart"
97-
builder_factories: ["apiTableBuilder"]
98-
build_extensions: {"lib/json_serializable.dart": ["tool/readme/api.md"]}
99-
build_to: source
100-
auto_apply: root_package
101-
runs_before: ["_readme_builder"]
102-
10395
_readme_builder:
10496
import: "tool/readme_builder.dart"
10597
builder_factories: ["readmeBuilder"]
106-
build_extensions: {"tool/readme/api.md": ["README.md"]}
98+
build_extensions: {"tool/readme/readme_template.md": ["README.md"]}
10799
build_to: source
108100
auto_apply: root_package
109101
required_inputs: ['.dart']

json_serializable/example/example.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,19 @@ part 'example.g.dart';
88

99
@JsonSerializable()
1010
class Person {
11-
final String firstName;
12-
final String lastName;
11+
/// The generated code assumes these values exist in JSON.
12+
final String firstName, lastName;
13+
14+
/// The generated code below handles if the corresponding JSON value doesn't
15+
/// exist or is empty.
1316
final DateTime? dateOfBirth;
17+
1418
Person({required this.firstName, required this.lastName, this.dateOfBirth});
19+
20+
/// Connect the generated [_$PersonFromJson] function to the `fromJson`
21+
/// factory.
1522
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
23+
24+
/// Connect the generated [_$PersonToJson] function to the `toJson` method.
1625
Map<String, dynamic> toJson() => _$PersonToJson(this);
1726
}

0 commit comments

Comments
 (0)