통조림

[Flutter] JsonSerializable & Freezed 본문

Software/Flutter

[Flutter] JsonSerializable & Freezed

고랭지참치 2023. 8. 18. 11:51

💡 모델 클래스 코드 작성은 매우 반복적인 작업이다. 필드의 규모에 따라서 반복되는 코드작성 또한 늘어난다. Code generator는 작업시간을 줄이기 위해 코드 제작 자동화 기능을 개발자에게 제공한다.

 

라이브러리 소개


JsonSerializable은 toJson과 fromJson 메소드를 자동으로 제작하는 기능을 지원한다.

Flutter에서 대표적으로 사용되는 Code generator 라이브러리에는 Json Serializable과 Freezed가 있다.

  • Json Serializable

https://pub.dev/packages/json_serializable

json_annotation | Dart Package

  • Freezed

freezed | Dart Package

freezed_annotation | Dart Package

추가적으로 builde_runner 라이브러리가 있다. Json Serializable와 Freezed에서 자동제작을 위해서 작성한 코드를 저장하고

flutter pub run build_runner **build(watch)**

명령어를 터미널에 입력하면 양식에 코드와 파일을 자동으로 생성한다.

  • Builde runner

build_runner | Dart Package

 

 

Json Serializable


JsonSerializable은 toJson과 fromJson 메소드를 자동으로 제작하는 기능을 지원한다.

직접 Json직렬화 코드를 작성

import 'dart:convert';

class User {
  final String name;
  final int age;

  User(this.name, this.age);

  String toJson(){
		Map<String, dynamic> userMap = {
			'name' : name,
			'age' : age,
		};
		return jsonEncode(userMap);
	}

	factory User.fromJson(Map<String, dynamic> jsonData) {
	    return User(
	      name: jsonData['name'],
	      age: jsonData['age'],
	    );
	  }
}

‘name’, ‘age’ 같이 직접 String값을 입력해줘야 하므로, 필드가 많아질 경우 직접 작성해야하는 코드의 줄도 많아지고 오타를 칠 경우 어디서 에러가 난 건지 디버깅하기도 어렵다. 🤑

이제 Json Serializable 라이브러리를 활용해 자동 직렬화를 누려보자.

Json Serializable 라이브러리를 활용해 자동으로 Json직렬화 코드를 작성

import 'package:json_annotation/json_annotation.dart';

// 작성하는 파일이름 뒤에 .g.dart를 붙혀서 작성한다.
// 작성 바로 뒤에 에러경고가 나오겠지만 무시한다.
part 'user.g.dart'; 

// 해당 클래스를 JsonSerializable로 직렬화시키겠다는 annotation
@JsonSerializable()
class User {
  final String name;
  final int age;

  User(this.name, this.age);

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

위와 같이 똑같은 문법으로 작성한 뒤 터미널에

flutter pub run build_runner **build**

명령어를 입력하면

위와 같은 안내가 나오고 같은 디렉토리 내에 user.g.dart 파일이 생성된 것을 볼 수 있다.

💡 만약 builde_runner 명령어 마지막에 build 대신 watch 를 대신 넣어주면 build_runner가 지속적으로 코드의 변화를 감지하여, annotion의 영향을 받는 프로젝트 내 모든 클래스들의 변화에 맞게 코드를 실시간으로 재생성한다.

part of 'user.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

User _$UserFromJson(Map<String, dynamic> json) => User(
      json['name'] as String,
      json['age'] as int,
    );

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
      'name': instance.name,
      'age': instance.age,
    };

이제 User.toJson() User.fromJson() 메소드를 바로 사용할 수 있다! 😃

 

 

Freezed


Freezed는 클래스가 제공해야하는 메소드들을 자동으로 구현해주는 code generator 라이브러리입니다. 또한 immutable한 데이터를 유지할 수 있도록 해줍니다.

Freezed는 아래와 같이 코드를 작성합니다.

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user_model.freezed.dart';

@freezed
class UserModel with _$UserModel {
  factory UserModel({
    required String id,
    required String name,
  }) = _UserModel;
}

Json Serializable를 사용할 때와 같이 똑같은 문법으로 작성한 뒤 터미널에

flutter pub run build_runner **build** (build 혹은 watch)

명령어를 입력하면 해당 디렉토리 내에 user_model.freezed 파일이 생성된 것을 확인할 수 있습니다.

만약에 toJson(), fromJson() 코드를 함께 생성하고 싶다면 Json Serializable관련 라이브러리가 프로젝트에 import가 되어 있는 상태에서 위에 코드에서 다음과 같이 주석이 추가된 부분만 추가해주면 됩니다.

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user_model.freezed.dart';
part 'user_model.g.dart'; // toJson, fromJson 생성을 위한 import

@freezed
class UserModel with _$UserModel {
  factory UserModel({
    required String id,
    required String name,
  }) = _UserModel;

	// toJson, fromJson 생성을 위한 코드
  factory UserModel.fromJson(Map<String, dynamic> json) =>
      _$UserModelFromJson(json);
}

💡 만약 필드 내 프로퍼티들을 mutable하게 관리하고 싶다면 @freezed 어노테이션 대신 @unfreezed 어노테이션을 사용하면 된다. 그리고 mutable하게 관리하고 싶은 프로퍼티만 final로 선언해주면 된다.

Freezed를 통해 자동생성된 코드에서 toString(), hashCode, copyWith() map() 와 같은 메소드들을 사용할 수 있다. 🥰

'Software > Flutter' 카테고리의 다른 글

[Dart] 클래스 Modifier  (0) 2024.04.02
[Flutter]GoRouter Redirection  (0) 2024.04.02
[Flutter]Variable Font  (0) 2023.08.18
Flutter 2.8 업데이트 내용  (2) 2021.12.24
Flutter web Tutorial 디자인 - turorial_coach_mark 플러그인  (0) 2021.08.31