수동 직렬화에 이어서 다트와 플러터에서 json_annotation패키지를 이용하여 자동 직렬화를 하는 방법을 알아보겠습니다. 수동 직렬화에 비해 어떤 점이 좋을까요? 수동 직렬화는 이쪽 포스트를 참조해 주세요.
json_annotation 패키지의 자동 직렬화
json_annotation패키지의 자동 직렬화를 사용하려면 수동 직렬화에 비해 부수적인 몇 가지 작업이 더 필요합니다. 하지만 올바른 사용자 정의 타입을 사용하는 장점으로 인해 이러한 추가 작업을 보상해 줍니다.
자동 직렬화는 다트의 어노테이션을 사용하여 직렬화를 수행할 Dart코드를 생성하는 프로세스를 구성하게 되는데, Dart에서 어노테이션은 자바와 같은 여타 언어와 마찬가지로 메타데이터를 첨부하는 선언적인 방법입니다. 예를 들어 클래스에 붙이는 JsonSerializable 어노테이션은 해당 클래스에 대한 직렬화 코드를 생성해야 한다고 코드 생성기에 알려줍니다. 이 어노테이션은 json_annotation 패키지에 포함되어 있는데요. 이 패키지는 Dart에 포함되어 있지 않으므로 pubspec.yaml파일의 종속성에 추가한 후 임포트 하여 사용해야 합니다.
이제 실습을 통해 자동 직렬화를 설정하고 코드를 생성해 보겠습니다. 여기 아래에 User클래스가 있습니다.
이 클래스에 json_annotation 패키지 어노테이션을 사용해서 Dart 직렬화 코드 생성을 해보도록 하겠습니다. 현재 위 코드의 toJson은 수동으로 직렬화를 하는 메소드 입니다. 앞으로 과정과 함께 비교해 보세요. 이제 json_annotaion 패키지를 쓰기 위해서는 위에서 언급했던 것처럼 pubspec.yaml파일에 종속성을 추가해야 합니다.
json_annotaion 종속성 추가
종속성을 추가하는 방법은 두가지 방법이 있습니다.
첫 번째는 dart pub add 혹은 flutter pub add 커맨드로 추가하는 방법입니다. 커맨드 창에서 아래 명령어를 실행해 주세요.
#dart
dart pub add json_annotation
#flutter
flutter pub add json_annotation
두 번째 방법은 pubspec.yaml파일에 종속성 부분에 가져오고 싶은 패키지와 버전명을 적은 후 dart pub get을 실행시키면 됩니다. vscode에서는 pubspec.yaml이 저장될 때마다 pub get이 자동으로 실행돼 패키지를 인스톨해줍니다. 본 실습에서는 두 번째 방법을 사용하였습니다.
위와 같이 종속성에 패키지를 추가해 주었고, 파일을 저장하게되면 vscode에서 자동으로 패키지를 가져와서 인스톨하게 됩니다. 만약 자동으로 실행이 안된다면 pub get을 커맨드에서 실행해 주세요. 이제 클래스에서 아래처럼 패키지를 import할 수 있게 되었습니다.
import 'package:json_annotation/json_annotation.dart';
만약에 에러가 계속 난다면 pub.dev에서 패키지를 검색한 후 업데이트된 버전을 사용해 주세요.
JsonSerializable 어노테이션 사용하기
이제 클래스에서 import하여 어노테이션을 사용하겠습니다.
JsonSerializable 어노테이션을 User 클래스에 추가하였습니다. import에서 방금 인스톨한 패키지를 가져오고 있으므로 어노테이션을 사용할 수 있다는 점을 기억해 주세요.
json_serializable, build_runner 종속성 추가
이제 코드 생성기인 json_serializable과 빌드 실행기인 build_runner에 대한 종속성을 추가해야 됩니다. 이번에도 역시 pubspec.yaml파일에 종속성을 추가하겠습니다.
이 두 패키지는 런타임에 사용되지 않으며 애플리케이션과 함께 배포되지도 않습니다. 따라서 json_annotation과는 달리 dev_dependencies섹션에 패키지를 추가하면 됩니다. 파일을 저장하고 pub get이 실행되어 패키지가 인스톨되었습니다.
user.dart파일에서 part키워드와 파일 이름인 user.g.dart가 있는 part 파일을 추가하겠습니다.
user.dart파일 안에서 쓰고 있으므로 part뒤에 오는 앞에 이름이 같아야 합니다. 아직 파일이 존재하지 않기 때문에 vscode에서는 에러가 표시되고 있습니다. 파일 생성하여 에러를 없애겠습니다.
build_runner로 파일 생성하기
프로젝트의 루트 폴더에서 pub run build_runner build 명령어를 실행하여 파일을 생성하겠습니다.
처음 이 명령어를 실행하면 조금 시간이 걸리지만, 두 번째 실행부터는 상당히 빨라집니다. 탐색창을 살펴보면 파일이 생성된 걸 확인할 수 있습니다.
user.g.dart파일이 생성되었고 user.dart파일의 에러도 사라졌습니다. user.g.dart파일을 열어보면 아래와 같습니다.
제일 맨 위 주석에 이 파일을 수정하지 말라고 되어있습니다. _$UserToJson 메소드를 보면 User를 받아 문자열 키와 동적 값이 포함된 맵을 반환해주고 있습니다. 이 반환하는 맵을 이용하면 jsonEncode함수로 JSON을 생성할 수 있습니다. 현재 User 클래스는 4개 필드만 존재하지만, 수십개의 필드를 수동으로 map으로 변환하는 메소드를 만드는 건 여간 귀찮은 일인데요. 이걸 자동으로 만들어 줍니다. 성가신 타이포 에러를 없애주는 건 덤이겠네요. 이제 user.dart파일로 돌아가서 _$UserToJson 함수를 사용해 보겠습니다.
part 사용하여 자동 생성된 함수 사용하기
part를 사용해서 파일을 포함하면 기본적으로 이 파일에 함수를 복사 붙여 넣기를 하는 것과 같이 작동합니다.
클래스에 toJson2메소드를 추가했습니다. _$UserToJson함수를 호출하고 클래스의 현재 인스턴스인 this를 전달합니다. 반환되는 값을 다시 jsonEncode에 전달해 직렬화를 해주고 json 문자열을 리턴해줍니다. jsonEncode를 사용하기 위해서는 dart.convert 패키지를 import 해줘야 합니다.
이제 메인 함수에서 json 결과값을 확인해 보겠습니다.
직렬화가 된 json데이터가 잘 호출되고 있습니다.
마지막으로 카멜 케이스 대신 스네이크 케이스로 바꿔보겠습니다.
자동으로 카멜 케이스(camel case)로 바꾸기
User클래스에서 FieldRename속성을 JsonSerialization 어노테이션에 추가하고 snake로 설정하였습니다. 이렇게 해주면 Dart 클래스의 카멜케이스 이름을 JSON에서 스네이크 케이스로 변환해 줍니다. 다시 코드 생성기를 실행하고 출력 결과를 살펴보겠습니다.
이름이 스테이크 케이스로 출력이 되는 걸 확인할 수 있습니다. json_annotation 패키지의 자동 직렬화의 장점으로 어노테이션을 사용하면 할 수 있는 일이 훨씬 더 많습니다. 더 많은 기능은 json_annotation 패키지 문서를 확인해 주세요.
여기까지 수고하셨습니다. 만약 속성이 몇 개 없어서 오타 가능성이 없다면 수동 직렬화 메서드를 만드는 것이 적합할 수도 있습니다. 자동 직렬화를 사용하면 어노테이션을 붙여주는 작업이 더 필요하지만, 수작업에서 오는 에러를 사전에 없애주고 더 많은 제어를 자동으로 제공해줍니다. 만약 파일이 분리되는 것이 싫다면 자동으로 생성한 후 함수만 카피해서 가져오는 방식으로 이용해도 편리할 것 같습니다.
'프로그래밍 > Flutter' 카테고리의 다른 글
[flutter 상태관리] 2. stateless widget (스테이트리스 위젯) (0) | 2022.05.31 |
---|---|
[flutter 상태 관리] 1. 선언형(Declarative) 상태 관리 (0) | 2022.05.31 |
[flutter] Dart, JSON 수동 직렬화(Serialization) 하기 (0) | 2022.05.17 |
[Flutter] Dart, 비동기 처리의 에러 처리 (0) | 2022.05.10 |
[Flutter] Dart, async / await 비동기 처리 (0) | 2022.05.09 |
댓글