json_serializable.dart icon indicating copy to clipboard operation
json_serializable.dart copied to clipboard

Level of indirection for getting rid of all boilerplate code

Open modulovalue opened this issue 2 years ago • 3 comments

Hello @kevmoo

Have you considered adding a level of indirection for getting rid of the boilerplate that json_serializable currently requires?

The rough idea is to instead of having to annotate the structure that you want to instantiate, to annotate the shape of the structure that you want to instantiate.

Here is a more concrete example:

// [...]

part 'example.g.dart';

@JsonSerializable()
class Person {
  /// The generated code assumes these values exist in JSON.
  final String firstName, lastName;

  /// The generated code below handles if the corresponding JSON value doesn't
  /// exist or is empty.
  final DateTime? dateOfBirth;

  Person({required this.firstName, required this.lastName, this.dateOfBirth});

  /// Connect the generated [_$PersonFromJson] function to the `fromJson`
  /// factory.
  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);

  /// Connect the generated [_$PersonToJson] function to the `toJson` method.
  Map<String, dynamic> toJson() => _$PersonToJson(this);
}

Would become:

// === example.dart ===

// [...]

part 'example.g.dart';

@JsonSerializable()
abstract class Person_ {
  String get firstName;
  
  String get lastName;

  DateTime? get dateOfBirth;
}

// === example.g.dart ===

// This should be fully derivable from Person_ above.
@JsonSerializable()
class Person implements Person_ {
  @override
  final String firstName;
  @override
  final String lastName;
  @override
  final DateTime? dateOfBirth;

  Person({required this.firstName, required this.lastName, this.dateOfBirth});

  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);

  /// Connect the generated [_$PersonToJson] function to the `toJson` method.
  Map<String, dynamic> toJson() => _$PersonToJson(this);
}

// [...]

I have been using this approach with great success and I believe it could significantly improve this package too.

Do you think that could work for the use cases that json_serializable attempts to solve, and if not, could you perhaps point out some of the concerns that you have with this approach?

Thanks!

modulovalue avatar May 17 '22 13:05 modulovalue

json_serializable is already pretty complex, but I could see the value here.

The WIP Dart macro work would be a better fit her, but I see where you're going.

kevmoo avatar May 17 '22 18:05 kevmoo

Thank you for the response @kevmoo.

The augmented libraries feature could potentially introduce another source of context sensitivity to the dart grammar or be moderately breaking.

I'm just trying to see if the most important potential clients of augmented libraries have considered this approach yet.

If it would keep the language much simpler, do you think that this approach could work for you? (Your answer is not binding, just a quick answer based on intuition would be enough for now.)

Thanks!

modulovalue avatar May 17 '22 23:05 modulovalue

serdes_json implements this idea already.

SoftWyer avatar Jul 07 '22 13:07 SoftWyer

I'm closing this issue because it is stale.

modulovalue avatar Feb 07 '23 17:02 modulovalue