반응형

 

JSON은 상당히 편리하면서 직관적인 데이터 형식이죠.

그래서 사람들이 많이 사용합니다.

 

코딩을 하다보면, json을 그대로 사용하기 보다는 보통 필요한 데이터 형을 class로 만들고 이를 json으로 encoding/decoding 하는 방식으로 많이 사용합니다.

 

그런데  매번 class 만들고 fromJson(), toJson()을 만들어서 사용하는것이 상당히 번거롭고, 실수할 때가 많습니다.

 

그래서 fromJson, toJson을 구현해주는 모듈들이 있죠.

대표적으로 json_serializable 이 있죠.

이를 활용하면 쉽게 json 변환이 가능한 data class를 정의 할 수 있습니다.

 

저는 요즘 freezed 라는 모듈을 주로 사용합니다.

 

freezed 2.5.7

https://pub.dev/packages/freezed

 

freezed | Dart package

Code generation for immutable classes that has a simple syntax/API without compromising on the features.

pub.dev

 

이 freezed 는 json_serialiazble 을 이용하여 data class를 구현해주는 모듈인데요. 제가 이를 사용하게 된 계기는 deep copy 때문이었습니다.

 

freezed는 fromJson, toJson 뿐만 아니라 copyWith() 함수를 자동으로 구현 해줍니다. 그리고 copyWith() 를 수행할때 멤버들의  copyWith()를 수행해서 전체가 복사가 됩니다.

이것이 하나의 큰 장점이고,

freezed 로 선언된 data class는 내부 데이터를 변경할 수 없습니다.

변경하려면, copyWith()로 특정 데이터만 변경해서 복사해서 사용해야 합니다.

그렇지 않고 변경가능한 class를 만들고 싶다면, @unfreezed를 이용합니다.

 

 

주의점!

간혹  freezed 로 정의한 class의 멤버중에 freezed로 되어있지 않은 class들을 데이터로 포함할 경우가 있습니다.

그런데 간혹, toJson() 이 정상적으로 동작하지 않을때도 있는데요.

이럴때 toJson()이 불리도록 explicitToJson  설정이 필요할때가 있습니다.

@unfreezed
class MyDataModel with _$MyDataModelModel {
  @JsonSerializable(explicitToJson: true)

  factory MyDataModel({
    required int id,
    required String name,
    DateTime? created_at,
    DateTime? updated_at,
    required Map<String, Health> data,
    bool? is_demo,
  })= _MyDataModel;

예를 들면 위와 같이 클래스를 정의한 경우, Health라는 class에 fromJson, toJson 을 구현 해놨다 하더라도, MyDataModel의 toJson()을 호출할때 Health의 toJson()이 호출되지 않습니다.

이유는 자동으로 생성된 코드에 Health의 toJson()을 호출하는 코드가 생성되지 않기 때문인데요.

이런 경우, toJson()이 불리도록,   @JsonSerializable(explicitToJson: true) 을 class 밑에 선언해 줍니다.

 

#해피코딩

+ Recent posts