피트니스 산업과 IT, 그리고 스타트업

IT

Dart 데이터 직렬화와 역직렬화

핏더스트리 2025. 4. 10. 19:13
728x90
반응형

Dart 데이터 직렬화와 역직렬화

플러터로 앱을 개발하다 보면 백엔드와 데이터를 주고받는 일이 필수입니다. 서버에서 데이터를 받아오거나, 서버로 데이터를 전송할 때 대부분 JSON이라는 형식을 사용하게 되죠. 하지만 JSON은 단순한 문자열일 뿐이고, 우리가 실제로 사용하는 건 Dart의 객체입니다. 그렇다면 이 둘을 어떻게 자연스럽게 오갈 수 있을까요?

 

바로 이때 필요한 것이 직렬화(Serialization)역직렬화(Deserialization)입니다. 이번 글에서는 Dart에서 JSON 데이터를 어떻게 직렬화하고 역직렬화하는지, 그리고 그 과정에서 어떤 점들을 주의해야 하는지 예제와 함께 알아보겠습니다.

 

 

직렬화와 역직렬화란 무엇인가?

먼저 용어부터 정확히 짚고 넘어갈 필요가 있습니다.

 

  • 직렬화(Serialization)란, 객체를 서버에 보내거나 로컬에 저장할 수 있도록 Map → JSON 문자열 형식으로 바꾸는 것을 말합니다.
  • 반대로 역직렬화(Deserialization)란, JSON 문자열 → Map → Dart 객체로 되돌리는 과정을 뜻합니다.

 

Dart에서 이 과정을 도와주는 것이 바로 dart:convert 패키지입니다. 이 안에는 jsonEncode()jsonDecode()라는 두 개의 핵심 함수가 들어있어요.

 

예를 들어, 아래는 MapJSON 문자열로 직렬화하는 코드입니다.

import 'dart:convert';

void main() {
  Map<String, dynamic> myInfo = {
    "name": "이지원",
    "age": 20,
  };

  String jsonString = jsonEncode(myInfo);
  print(jsonString); // {"name":"이지원","age":20}
}

 

그리고 JSON 문자열을 다시 Map으로 바꾸는 역직렬화 과정은 이렇게 됩니다.

import 'dart:convert';

void main() {
  String jsonString = '{"name": "이지원", "age": 20}';

  var map = jsonDecode(jsonString);
  print(map); // {name: 이지원, age: 20}
  print(map.runtimeType); // Map<String, dynamic>
}

 

이처럼 Dart에서는 Map을 중간다리로 사용해 객체와 문자열(JSON) 사이를 오갈 수 있게 합니다. 이 과정을 잘 이해하고 있어야 나중에 서버 연동이나 로컬 데이터 저장에서 무리가 없습니다.

 

 

Dart 객체를 JSON과 주고받기 

Map으로 JSON을 다루는 것만으로도 간단한 앱을 만드는 데는 큰 문제가 없지만, 실제 개발에서는 각 데이터를 하나의 클래스(객체)로 정의해서 쓰는 것이 훨씬 안전하고 효율적입니다. 왜냐하면 객체로 만들어야 타입 오류도 줄고, 가독성도 높아지고, 실수도 줄일 수 있기 때문이죠.

 

예를 들어 아래와 같이 User라는 클래스를 만들어볼 수 있어요.

class User {
  User({
    required this.name,
    required this.age,
  });

  String name;
  int age;

  // 역직렬화: JSON(Map)을 → Dart 객체로
  User.fromJson(Map<String, dynamic> json)
      : this(
          name: json['name'],
          age: json['age'],
        );

  // 직렬화: Dart 객체를 → JSON(Map)으로
  Map<String, dynamic> toJson() {
    return {
      "name": name,
      "age": age,
    };
  }
}

 

이제 이 클래스를 바탕으로 JSON 문자열을 객체로 바꾸고, 다시 문자열로 바꿔볼 수 있어요.

import 'dart:convert';

void main() {
  String jsonString = '{"name": "이지원", "age": 20}';
  
  // Step 1: JSON 문자열을 Map으로
  Map<String, dynamic> jsonMap = jsonDecode(jsonString);

  // Step 2: Map을 Dart 객체(User)로
  User user = User.fromJson(jsonMap);
  print(user.name); // 이지원

  // Step 3: Dart 객체를 다시 JSON(Map)으로
  String newJson = jsonEncode(user.toJson());
  print(newJson); // {"name":"이지원","age":20}
}

 

정리하자면,


JSON → jsonDecode() → Map<String, dynamic> → fromJson() → Dart 객체
Dart 객체 → toJson() → Map<String, dynamic> → jsonEncode() → JSON

이런 흐름이 매우 중요합니다.

 

 

중첩된 JSON과 복합 객체의 처리

JSON 구조는 단순한 key-value 쌍만으로 이루어져 있지 않고, 내부에 다른 객체나 리스트가 중첩되어 있는 경우가 흔합니다. 이럴 때는 중첩된 구조에 맞춰 Dart 클래스를 여러 개 정의하고, 각 클래스에서 fromJsontoJson 메서드를 구현해 연결해야 합니다.

 

예를 들어 다음과 같은 JSON을 살펴볼게요.

{
  "name": "오상구",
  "age": 7,
  "isMale": true,
  "favorite_foods": ["삼겹살", "연어", "고구마"],
  "contact": {
    "mobile": "010-0000-0000",
    "email": null
  }
}

 

이를 Dart에서 처리하려면 Pet 클래스와 Contact 클래스를 각각 만들어야 합니다.

class Pet {
  final String name;
  final int age;
  final bool isMale;
  final List<String> favoriteFoods;
  final Contact contact;

  Pet({
    required this.name,
    required this.age,
    required this.isMale,
    required this.favoriteFoods,
    required this.contact,
  });

  factory Pet.fromJson(Map<String, dynamic> json) {
    return Pet(
      name: json["name"],
      age: json["age"],
      isMale: json["isMale"],
      favoriteFoods: List<String>.from(json["favorite_foods"]),
      contact: Contact.fromJson(json["contact"]),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      "name": name,
      "age": age,
      "isMale": isMale,
      "favorite_foods": favoriteFoods,
      "contact": contact.toJson(),
    };
  }
}

class Contact {
  final String mobile;
  final String? email;

  Contact({
    required this.mobile,
    required this.email,
  });

  factory Contact.fromJson(Map<String, dynamic> json) {
    return Contact(
      mobile: json["mobile"],
      email: json["email"],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      "mobile": mobile,
      "email": email,
    };
  }
}

 

이런 방식으로 구조화된 JSON을 안전하게 관리하고, 코드의 유지보수성을 높일 수 있습니다. 실제 서비스에서는 데이터가 점점 더 복잡해지기 때문에 이러한 클래스 기반 설계가 매우 중요합니다.

 

 

마치며...

Dart에서 JSON 데이터를 다루는 방법은 단순히 문자열을 Map으로 바꾸는 것을 넘어서, 객체 지향적으로 관리할 수 있는 구조로 확장해 나가는 것이 핵심입니다. 직렬화와 역직렬화는 서버와 클라이언트 간의 소통을 원활하게 하기 위해 꼭 필요한 개념이며, 이 과정을 잘 설계해두면 API 연동이나 로컬 데이터 저장에서도 안정적으로 데이터를 처리할 수 있습니다.

 

Flutter 개발을 한다면 JSON과 Dart 객체 간 변환은 더 이상 선택이 아닌 필수입니다. 오늘 소개한 개념들을 잘 익혀두면, 앞으로 다양한 상황에서 유연하게 데이터를 다루는 능력을 갖추게 될 거예요!


세 줄 요약

  • Dart에서 JSON을 다루기 위해선 jsonEncode, jsonDecode와 Map 변환 과정을 반드시 거쳐야 해요.
  • 안전한 데이터 처리와 유지보수를 위해 fromJson, toJson을 활용한 클래스 기반 구조화가 중요해요.
  • 중첩된 JSON 구조도 Dart 클래스 설계로 효율적으로 관리할 수 있으니 연습해 둘 필요가 있어요.
728x90
반응형