k-paxian / dart-json-mapper

Serialize / Deserialize Dart Objects to / from JSON
https://pub.dev/packages/dart_json_mapper
Other
399 stars 33 forks source link

Pass field name `prefix` to work together with `flatten: true` attribute in @JsonProperty meta #174

Closed luissalgadofreire closed 2 years ago

luissalgadofreire commented 2 years ago

I have a dart object that includes a field of type Money, which itself is composed of amount and currency:

class Account {

  final String id;
  final String type;
  final String subtype;
  final String origin;
  final String name;
  final String status;
  final String currency;
  final Money balance; <== value object
  ...
}

Money looks something like this:

class Money {
  final int amount;
  final String currency;

  const Money(this.amount, this.currency);
  ...
}

The above is to be mapped for use by sqflite, therefore the target JSON must be a flat JSON, like:

{
  "id": String,
  "type": String,
  "subtype": String,
  "origin": String,
  "name": String,
  "status": String,
  "currency": String,
  "balanceAmount": int;      <== value object
  "balanceCurrency": String; <== value object
}

I understand I can use @JsonProperty(flatten: true) to make it work closely to what I need. But to avoid conflict with other Money instances I may have in the source object, a prefix would come handy.

Would it be possible to have something like:

@jsonSerializable
class Account {

  final String id;
  final String type;
  final String subtype;
  final String origin;
  final String name;
  final String status;
  final String currency;

  @JsonProperty(flatten: true, prefix: 'balance')
  final Money balance; <== value object
  ...
}

That way, dart-json-mapper would know that it would have to prefix balance to the names of properties currency and amount of Money, resulting in the above mentioned JSON:

{
  "id": String,
  "type": String,
  "subtype": String,
  "origin": String,
  "name": String,
  "status": String,
  "currency": String,
  "balanceAmount": int;      <== value object
  "balanceCurrency": String; <== value object
}
k-paxian commented 2 years ago

Sure it's totally possible to introduce that, one thing I would suggest is to re-use the name attribute to pass your prefix value, to not introduce custom prefix attribute for one use case only. What do you think?

When flatten: true, name: does not have any sense, and we will bring that sense as a prefix

@jsonSerializable
class Account {

  final String id;
  final String type;
  final String subtype;
  final String origin;
  final String name;
  final String status;
  final String currency;

  @JsonProperty(flatten: true, name: 'balance')
  final Money balance; <== value object
  ...
}

Thank you for the idea!

luissalgadofreire commented 2 years ago

Thanks for the quick reply.

So, in this context, name would work as a prefix, added before currency and amount, and these would be capitalized, with end result balanceCurrency and balanceAmount, as in the example?

Sounds ok with me.

luissalgadofreire commented 2 years ago

By the way, I haven't tested it yet. Does flatten work multiple levels deep?

Any way, thanks for this great library.

k-paxian commented 2 years ago

By the way, I haven't tested it yet. Does flatten work multiple levels deep?

No, one level so far.

k-paxian commented 2 years ago

The casing aspect can be configured at a higher level, please read more here

balanceCurrency and balanceAmount would be a good fit for CaseStyle.camel

luissalgadofreire commented 2 years ago

OK, great.

I'm moving from json_serializable, so still have to get acquainted with this library in more detail.

Thanks again for the quick response.

k-paxian commented 2 years ago

Delivered. Merry Christmas ☃️ 🎄

luissalgadofreire commented 2 years ago

Great stuff. Thanks.

Best wishes.