본문 바로가기
Tech/flutter

[flutter] JSON 직렬화 아주 쉽게하기(Model Class 쉽게 만들기)

by 패드로 2020. 8. 19.

flutter로 각종 외부 api를 사용하거나, 서버를 통해 데이터를 받을 때,

혹은 내부 DB에 쿼리를 날려 데이터를 받을 때 보면 데이터 처리하는게 좀 귀찮은 부분이 있다.

 

JSON 데이터를 flutter에서 사용하기 위해서는 대부분의 언어가 그렇듯 일단 기본적으로 직렬화/파싱을 해줘야하는데, 플러터에서는 보통 데이터를 매핑할 수 있는 클래스를 별도로 만들어서 사용하게된다. 

웹 개발을 주로 해와서 response를 받으면 바로 response.data로 개발을 해왔던 나로써는 왜 이런 작업을 거치지? 라는 의문이 들었는데, 실제 개발을 해보니 의문이 풀렸다.

 

response 데이터 안에 title 이라는 정보가 있다고 하면 response["title"] 이런식으로 접근을 할 수 밖에 없는데 나중에 디버깅/유효성 판단에도 좋지 않을 뿐더러 깔끔한 구조의 앱을 만들기 위해서는 직렬화(Serialization)를 위한 클래스를 두는 것이 좋겠다는 결론을 내렸다.

 

관련해서 플러터 개발자 사이트에 아래와 같이 글이 있다.

 

https://flutter-ko.dev/docs/development/data-and-backend/json

 

JSON과 직렬화

어느 시점부터 웹 서버와 통신하지 않거나 구조화된 데이터를 적절하게 보관하지 않는 모바일 앱을생각하기 어려워졌습니다. 네트워크와 연결된 앱을 제작할 때, 결국에는 제법 괜찮은 JSON을사

flutter-ko.dev

번역체라 좀 이상하긴 하지만, 대략 깔끔하게 해석하자면 소규모 프로젝트에서는 그냥 일일히 코딩해서 넣고, 중대형 프로젝트에서는 그렇게 하면 버그 날수도 있고 찾기도 힘드니 라이브러리 써서 자동 생성해서 써라. 라는 내용이다.

 

오준석의 생존코딩이라는 강좌를 보고있는데 api를 다루는 간단한 내용 중 json을 다루는 부분이 있어 그쪽의 json 데이터를 핸들링하기위한 코드를 보면 대략 이렇다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Store {
  String addr;
  String code;
  String createdAt;
  double lat;
  double lng;
  String name;
  String remainStat;
  String stockAt;
  String type;
  Store(
      {this.addr,
      this.code,
      this.createdAt,
      this.lat,
      this.lng,
      this.name,
      this.remainStat,
      this.stockAt,
      this.type});
  Store.fromJson(Map<String, dynamic> json) {
    addr = json['addr'];
    code = json['code'];
    createdAt = json['created_at'];
    lat = json['lat'];
    lng = json['lng'];
    name = json['name'];
    remainStat = json['remain_stat'];
    stockAt = json['stock_at'];
    type = json['type'];
  }
  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['addr'= this.addr;
    data['code'= this.code;
    data['created_at'= this.createdAt;
    data['lat'= this.lat;
    data['lng'= this.lng;
    data['name'= this.name;
    data['remain_stat'= this.remainStat;
    data['stock_at'= this.stockAt;
    data['type'= this.type;
    return data;
  }
}
 
cs

9개의 데이터를 가진 모델을 만들기위한 코드 치고는 꽤 많고... 귀찮은 일이다. 모델이 한두개라면 하겠는데 많아지면 매우 귀찮고 오타도 많이 나겠지?

 

그래서 위 홈페이지에서 프로젝트가 커졌을 때 추천하는 방법은 자동 코드 생성기를 쓰는 방법이다.

pubspec.yaml에 아래와 같이 쓰이는 아이들을 추가해주고 pub get을 해주자.

 

dependencies:  

  json_annotation: ^2.0.0

dev_dependencies:  

  build_runner: ^1.0.0

  json_serializable: ^2.0.0

 

빌드 러너와 json_serializable은 모두 빌드할때만 쓰이는 코드기때문에 dev_dependencies아래 적용해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
part 'store2.g.dart';
 
@JsonSerializable(
    checked: true, createFactory: true, fieldRename: FieldRename.snake)
class Store {
  String addr;
  String code;
  String createdAt;
  double lat;
  double lng;
  String name;
  String remainStat;
  String stockAt;
  String type;
  Store(
      {this.addr,
      this.code,
      this.createdAt,
      this.lat,
      this.lng,
      this.name,
      this.remainStat,
      this.stockAt,
      this.type});
 
  factory Store.fromJson(Map<String, dynamic> json) => _$StoreFromJson(json);
  Map<String, dynamic> toJson() => _$StoreToJson(this);
}
 
 
cs

그럼 이정도로 코드가 줄어든다. 많이 줄어들었나? 싶긴 한데.. json 안에 ["변수명"] 이런식으로 접근을 안해도 된다는 사실은 나쁘지 않았다.

이 코드를 작성 후 아래 명령어를 실행해주면 알아서 새로운 코드가 생성된다.(_파일명.g.dart)파일

명령어 : flutter pub run build_runner build

 

그런데.. 세상은 넓고 오픈소스는 많다고 했던가

데이터 정보만 넣으면 코드를 자동으로 생성해주는 깃헙 프로젝트가 있다.

이름도 직관적이다. 바로 JSON to Dart..

https://javiercbk.github.io/json_to_dart/ 

 

JSON to Dart

JSON to Dart Paste your JSON in the textarea below, click convert and get your Dart classes for free. Handcrafted by Javier Lecuona Github json_to_dart Code Twitter

javiercbk.github.io

사용법도 너무 편한게.. 그냥 api 보내놓고 응답 오면 복사해다가 붙여주면 자동으로 class.dart파일을 생성해준다.

위에 코드 자동 생성 방식을 옹호하기위해 여러가지 시도를 해봤는데 nested class에 대해서도 잘 대응해서 만들어주고 변수 타입에 대해서만 조금 신경써주면 된다는 점 빼고는 사용하기도 편하다.

 

클래스 명까지 정할 수 있어서 그냥 말그대로 복붙해서 사용 가능..소규모 프로젝트면 JSON to Dart를 쓸것같다.

다만 정식 flutter 제공은 아니고 배포자 찾아보니 그냥 일반 스타트업 CTO 외국인이더라. 언제 사라지거나 얘기치못한 오류의 발생 여부는 있...지만 뭐 탑재해서 쓰는 라이브러리도 아니고 그냥 웹 서비스니까 리스크도 없다.

그럼 이게 Best인가? 라는 생각이 들어 이것저것 찾아봤는데, json_serializable에서는 코드 자동 생성기가 갖고 있는 옵션들을 통해서 좀 더 flexible하게 쓸 수 있다는 장점이 있긴 하다.

예를 들면 체크 옵션을 통해서 데이터 유효성 검사를 좀 더 빡시게 할 수도 있고 camel_case를 kebab, pascal, snake case 등 여러가지 형태로 변환해서 쓸 수도 있고...(근데 뭐 대다수는 플러터에서 camel쓰고 json보낼때 snake를 쓸 것이기 때문에 json to dart의 단점으로 보기도 애매하다)

 

결론 :

json_to_dart 웹페이지 가서 그때그때 생성해서 쓰자

하지만 프로젝트 커지고 협업도 해야되고 세세한 옵션 설정도 해야하면 그냥 코드 생성기(json_annotation) 쓰자

--------------------------------

android studio 플러그인을 살펴보다보니 json_to_dart 기능을 하는 아이가 있다.

그냥 이거 쓰는게 제일 편할것 같다.

padro.tistory.com/172

 

[flutter] JSON 직렬화 더 쉽게하기(Model Class 쉽게 만들기)

[flutter] JSON 직렬화 아주 쉽게하기(Model Class 쉽게 만들기) [flutter] JSON 직렬화 아주 쉽게하기(Model Class 쉽게 만들기) flutter로 각종 외부 api를 사용하거나, 서버를 통해 데이터를 받을 때, 혹은 내..

padro.tistory.com

 

댓글