(+) Data Layer - response to model

별 λ‚΄μš©μ€ μ—†λŠ”λ° 일반적으둜 자주 μ“°μ΄λŠ” ν˜•νƒœλΌμ„œ 정리λ₯Ό ν•΄λ‘”λ‹€. APIν΄λΌμ΄μ–ΈνŠΈλ₯Ό μ΄μš©ν•΄μ„œ μ„œλ²„μ™€ 톡신을 ν•˜κ³  response λ₯Ό μˆ˜μ‹  λ°›κ²Œ 되면 이λ₯Ό κ°€μ§€κ³  λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•˜λŠ” model 둜 μ»¨λ²„νŒ…μ„ ν•΄μ€˜μ•Ό ν•˜λŠ”λ° 이 λ•Œ 일반적으둜 μ²˜λ¦¬ν•˜λŠ” 방식에 λŒ€ν•œ 정리이닀.

1. μ˜μ‘΄μ„±μœΌλ‘œ build_runner λ₯Ό μΆ”κ°€ν•œλ‹€.

build_runner λŠ” μ½”λ“œ 생성 및 λΉŒλ“œ κ΄€λ ¨ μž‘μ—…μ„ νŽΈλ¦¬ν•˜κ²Œ ν•΄μ£ΌλŠ” νˆ΄μ΄λ‹€. μ—¬κΈ°μ„œ μΆ”κ°€ν•΄μ£ΌλŠ” μ΄μœ λŠ” μ–΄λ…Έν…Œμ΄μ…˜μ„ 기반으둜 μ‘λ‹΅μœΌλ‘œ λ°›μ•„μ˜¨ 데이터λ₯Ό λͺ¨λΈμ— λ§€ν•‘ν•΄μ£ΌλŠ” 과정에 ν•„μš”ν•œ μ½”λ“œλ₯Ό μžλ™ 생성해주기 μœ„ν•¨μ΄λ‹€.

build_runnerλŠ” ν”ŒλŸ¬ν„°(Flutter) ν”„λ‘œμ νŠΈμ—μ„œ μ½”λ“œ 생성과 λΉŒλ“œ κ΄€λ ¨ μž‘μ—…μ„ μžλ™ν™”ν•˜κΈ° μœ„ν•œ λ„κ΅¬μž…λ‹ˆλ‹€. 일반적으둜 μ½”λ“œ 생성 μž‘μ—…μ€ 반볡적이고 번거둜운 μž‘μ—…μΌ 수 μžˆμŠ΅λ‹ˆλ‹€. build_runnerλŠ” μ΄λŸ¬ν•œ μž‘μ—…μ„ μžλ™ν™”ν•˜μ—¬ κ°œλ°œμžκ°€ 더 효율적으둜 μž‘μ—…ν•  수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€.

build_runnerλŠ” 주둜 ν”ŒλŸ¬ν„°μ˜ μ½”λ“œ 생성과 κ΄€λ ¨λœ μž‘μ—…μ— μ‚¬μš©λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ• λ…Έν…Œμ΄μ…˜(annotation)을 기반으둜 λͺ¨λΈ 클래슀, 라우트 μ„€μ •, λ¦¬μ†ŒμŠ€ 파일 λ“±μ˜ μ½”λ“œλ₯Ό μžλ™μœΌλ‘œ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 κ°œλ°œμžλŠ” 반볡적인 μž‘μ—…μ„ μˆ˜λ™μœΌλ‘œ μ²˜λ¦¬ν•˜μ§€ μ•Šκ³ , μžλ™ν™”λœ λ°©μ‹μœΌλ‘œ μ½”λ“œλ₯Ό μƒμ„±ν•˜κ³  μ—…λ°μ΄νŠΈν•  수 μžˆμŠ΅λ‹ˆλ‹€.

build_runnerλŠ” build.yaml νŒŒμΌμ„ 톡해 κ΅¬μ„±λ˜λ©°, μ£Όμš” λͺ…λ Ήμ–΄λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  • build_runner build: μ½”λ“œλ₯Ό μƒμ„±ν•˜κ³  λΉŒλ“œν•©λ‹ˆλ‹€.

  • build_runner watch: μ½”λ“œλ₯Ό μƒμ„±ν•˜κ³  λ³€κ²½ 사항을 κ°μ§€ν•˜μ—¬ μžλ™μœΌλ‘œ λΉŒλ“œν•©λ‹ˆλ‹€.

  • build_runner clean: 이전 λΉŒλ“œμ—μ„œ μƒμ„±λœ μ½”λ“œλ₯Ό μ‚­μ œν•©λ‹ˆλ‹€.

build_runnerλŠ” 주둜 μ½”λ“œ 생성, λ¦¬μ†ŒμŠ€ λ²ˆλ“€λ§, λ‹€κ΅­μ–΄ 지원 λ“±κ³Ό κ΄€λ ¨λœ μž‘μ—…μ— μ‚¬μš©λ©λ‹ˆλ‹€. μ½”λ“œ 생성 도ꡬ인 Freezed, json_serializable, injectable λ“±κ³Ό ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ ν”ŒλŸ¬ν„° μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 개발 생산성을 ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

2. μ˜μ‘΄μ„±μœΌλ‘œ json_serializable, json_annotation 을 μΆ”κ°€ν•œλ‹€.

json_serializable μ€μ‘λ‹΅μœΌλ‘œ λ°›μ•„μ˜¨ 데이터 json μ—μ„œ λͺ¨λΈλ‘œ μ»¨λ²„νŒ…μ„ ν•˜λŠ” ν•¨μˆ˜λ₯Ό μžλ™μœΌλ‘œ 생성해주기 μœ„ν•΄μ„œ

@JsonSerializable()

을 μ‚¬μš©ν•  것인데 이 λ•Œ ν•„μš”ν•œ μ˜μ‘΄μ„±μ΄λ‹€. μ‚¬μš©λ²•μ€ κ³΅μ‹λ¬Έμ„œμ— 잘 λ‚˜μ™€μžˆλŠ”λ° μ•„λž˜μ— 짧게 μ •λ¦¬ν•œλ‹€. 그리고 json_serializable 을 μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œ json_annotation 도 μ˜μ‘΄μ„±μœΌλ‘œ μΆ”κ°€ν•΄ μ€€λ‹€.

3. build_runner λ₯Ό μ΄μš©ν•΄μ„œ build λͺ…λ Ήμ–΄λ₯Ό μˆ˜ν–‰ν•œλ‹€.

μ•„λž˜μ™€ 같이 @JsonSerializable() 을 달아주고 build_runner 둜 λͺ…λ Ήμ–΄λ₯Ό μˆ˜ν–‰ν•˜λ©΄ μ›ν•˜λŠ” μ½”λ“œκ°€ 생성이 λ˜μ§€ μ•ŠλŠ”λ‹€.

import 'package:json_annotation/json_annotation.dart';

@JsonSerializable()
class SignInResponse {
  final String accessToken;
  final String refreshToken;
  final bool isProfileCompleted;

  const SignInResponse({
    required this.accessToken,
    required this.refreshToken,
    required this.isProfileCompleted,
  });

}
sign_in_response.g.dart must be included as a part directive in the input library with:
    part 'sign_in_response.g.dart';

κ·Έλž˜μ„œ part 'sign_in_response.g.dart'; λ₯Ό μ•„λž˜μ™€ 같이 μΆ”κ°€ν•΄μ£Όκ³  μ•„λž˜ λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•΄μ•Ό .g 파일이 λ§Œλ“€μ–΄μ§„λ‹€.

import 'package:json_annotation/json_annotation.dart';
part 'sign_in_response.g.dart';

@JsonSerializable()
class SignInResponse {
  final String accessToken;
  final String refreshToken;
  final bool isProfileCompleted;

  const SignInResponse({
    required this.accessToken,
    required this.refreshToken,
    required this.isProfileCompleted,
  });

}
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'sign_in_response.dart';

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

SignInResponse _$SignInResponseFromJson(Map<String, dynamic> json) =>
    SignInResponse(
      accessToken: json['accessToken'] as String,
      refreshToken: json['refreshToken'] as String,
      isProfileCompleted: json['isProfileCompleted'] as bool,
    );

Map<String, dynamic> _$SignInResponseToJson(SignInResponse instance) =>
    <String, dynamic>{
      'accessToken': instance.accessToken,
      'refreshToken': instance.refreshToken,
      'isProfileCompleted': instance.isProfileCompleted,
    };
dart run build_runner build

μžλ™ μƒμ„±λœ μ½”λ“œλ₯Ό μ‚¬μš©ν•΄μ„œ μ•„λž˜μ™€ 같이 factory λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•΄μ£Όμž.

import 'package:json_annotation/json_annotation.dart';

part 'sign_in_response.g.dart';

@JsonSerializable()
class SignInResponse {
  final String accessToken;
  final String refreshToken;
  final bool isProfileCompleted;

  const SignInResponse({
    required this.accessToken,
    required this.refreshToken,
    required this.isProfileCompleted,
  });

  factory SignInResponse.fromJson(Map<String, dynamic> json) {
    return _$SignInResponseFromJson(json);
  }
}

Last updated