Flutter에서 API 통신 및 데이터 관리

Baek Dong Hyun·2025년 1월 15일
1

1️⃣ Flutter에서 API 통신하는 방법

Flutter에서는 외부 서버와의 통신을 위해 다양한 패키지를 사용할 수 있으며, 사용 목적에 맞게 선택할 수 있습니다.

API 통신은 서버로부터 데이터를 받아오거나 서버로 데이터를 전송하기 위해 사용됩니다. Flutter에서는 주로 다음과 같은 패키지를 사용합니다.

1. http 패키지

  • Flutter에서 가장 기본적으로 사용하는 HTTP 클라이언트 패키지.
  • 간단한 요청(GET, POST 등)에 적합.
import 'package:http/http.dart' as http;
import 'dart:convert';

Future<void> fetchData() async {
  final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));

  if (response.statusCode == 200) {
    final data = jsonDecode(response.body);
    print(data);
  } else {
    throw Exception('Failed to load data');
  }
}

2. dio 패키지

  • 고급 기능을 지원하는 강력한 HTTP 클라이언트.
  • 인터셉터, 리퀘스트 취소, 타임아웃 설정, 파일 업로드/다운로드 지원.
import 'package:dio/dio.dart';

final dio = Dio();

Future<void> fetchData() async {
  try {
    final response = await dio.get('https://jsonplaceholder.typicode.com/posts/1');
    print(response.data);
  } catch (e) {
    print('Error: $e');
  }
}

3. GetX의 API 통신 기능

  • 상태 관리, 라우팅, 의존성 주입과 함께 API 통신 기능도 제공.
  • 간단한 앱에서는 빠르고 효율적이지만, 복잡한 네트워크 로직에는 한계가 있음.

4. graphql_flutter 패키지

  • GraphQL API와 통신을 위한 패키지.
  • 캐싱 및 실시간 데이터 업데이트 지원.
import 'package:graphql_flutter/graphql_flutter.dart';

final HttpLink httpLink = HttpLink('https://example.com/graphql');

ValueNotifier<GraphQLClient> client = ValueNotifier(
  GraphQLClient(
    link: httpLink,
    cache: GraphQLCache(store: HiveStore()),
  ),
);

✅ 장점:

  • GraphQL API와의 통합이 용이함.
  • 캐싱 및 실시간 데이터 업데이트 가능.

❗ 단점:

  • REST API보다 설정이 복잡함.
  • 프로젝트에 GraphQL 도입이 필요함.

5. chopper 패키지

  • Retrofit 스타일의 HTTP 클라이언트.
  • 인터셉터, 코드 생성을 통한 API 요청 간소화.
import 'package:chopper/chopper.dart';

part 'post_service.chopper.dart';

()
abstract class PostService extends ChopperService {
  (path: '/posts/{id}')
  Future<Response> getPost(('id') int id);

  static PostService create() {
    final client = ChopperClient(
      baseUrl: 'https://jsonplaceholder.typicode.com',
      services: [
        _$PostService(),
      ],
      converter: JsonConverter(),
    );

    return _$PostService(client);
  }
}

✅ 장점:

  • REST API 요청을 간결하게 작성 가능.
  • 코드 자동 생성을 통한 유지보수 편리.

❗ 단점:

  • 추가 설정이 필요하며 학습 곡선이 존재함.
  • build_runner를 통한 코드 생성을 필요로 함.

6. retrofit 패키지

  • Dart Retrofit 스타일의 HTTP 클라이언트.
  • dio와 결합해 더욱 강력한 기능 제공.
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';

part 'client.g.dart';

(baseUrl: "https://jsonplaceholder.typicode.com")
abstract class RestClient {
  factory RestClient(Dio dio, {String baseUrl}) = _RestClient;

  ("/posts/{id}")
  Future<HttpResponse> getPost(("id") int id);
}

✅ 장점:

  • dio와 결합해 인터셉터, 에러 핸들링 등 강력한 기능 지원.
  • Retrofit 스타일의 직관적인 API 작성.

❗ 단점:

  • 코드 생성 도구(build_runner) 사용 필요.
  • 추가적인 설정이 필요함.
  • 상태 관리, 라우팅, 의존성 주입과 함께 API 통신 기능도 제공.
  • 간단한 앱에서는 빠르고 효율적이지만, 복잡한 네트워크 로직에는 한계가 있음.
import 'package:get/get.dart';

Future<void> fetchData() async {
  final response = await GetConnect().get('https://jsonplaceholder.typicode.com/posts/1');
  if (response.statusCode == 200) {
    print(response.body);
  }
}

2️⃣ Flutter API 통신 패키지 비교 및 선택 이유

다양한 API 통신 패키지가 존재하지만, 프로젝트의 규모와 필요에 따라 적절한 패키지를 선택해야 합니다. 다음은 주요 Flutter API 통신 패키지의 비교입니다.

패키지장점단점주 사용 이유
http간단한 사용법, 가벼움인터셉터, 요청 취소, 파일 업로드 등의 고급 기능 부족작은 프로젝트나 간단한 요청 처리에 적합
dio고급 기능 지원(인터셉터, 요청 취소, 파일 업로드), 에러 핸들링 용이패키지 크기가 크고 설정이 복잡할 수 있음대규모 프로젝트나 복잡한 API 통신에서 사용
GetX상태 관리, 라우팅, 의존성 주입과 통합, 빠르고 간단함네트워크 로직 구조화 및 확장성 부족, 고급 네트워크 기능 부족빠른 개발이 필요한 소규모 프로젝트
graphql_flutterGraphQL API 통합, 실시간 데이터 처리 및 캐싱 지원REST API보다 설정이 복잡, GraphQL 도입 필요GraphQL 기반 서버와 통신 시 사용
chopperRetrofit 스타일, 코드 자동 생성, 유지보수 용이추가 설정 및 코드 생성 필요, 학습 곡선 존재REST API와의 직관적인 통신이 필요한 경우
retrofitdio와 결합해 강력한 기능 제공, 직관적인 API 작성build_runner 필요, 추가 설정 필요고급 네트워크 로직 구현 및 코드 일관성이 중요한 경우

3️⃣ 사람들이 많이 사용하는 패키지와 그 이유

1. dio

  • 가장 많이 사용되는 이유: 고급 기능(인터셉터, 요청 취소, 파일 업로드 등)을 폭넓게 지원.
  • 유연성: 복잡한 네트워크 로직에도 유연하게 대처 가능.
  • 유지보수 용이: 네트워크 레이어 분리가 쉬워 대규모 프로젝트에 적합.

2. http

  • 간편함: Flutter 기본 패키지로 간단한 API 통신에 적합.
  • 빠른 학습 곡선: 초보자도 쉽게 접근 가능.

3. GetX

  • 통합 솔루션: 상태 관리, 라우팅, 의존성 주입, API 통신을 하나의 패키지로 해결.
  • 빠른 개발: MVP나 프로토타입 앱 개발에 최적화.

4. retrofit

  • 코드 일관성: dio와 결합해 효율적인 네트워크 레이어 구성.
  • 직관적 API 작성: 코드 가독성이 뛰어나고 유지보수에 강점.

3️⃣ JSON 데이터 처리: json_serializable vs freezed

API 응답으로 받은 JSON 데이터를 모델로 변환하기 위해 Flutter에서는 **json_serializable**과 **freezed**를 많이 사용합니다.

1. json_serializable

  • 자동 JSON 직렬화/역직렬화 지원.
  • 코드 생성기로 간결한 데이터 모델 작성 가능.

✅ 사용 예시

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

()
class User {
  final int id;
  final String name;

  User({required this.id, required this.name});

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

🔧 의존성 추가

dependencies:
  json_annotation: ^4.8.1

dev_dependencies:
  build_runner: ^2.4.0
  json_serializable: ^6.6.1

⚡ 코드 생성

flutter pub run build_runner build

2. freezed

  • 불변 객체(Immutable Object) 생성.
  • 데이터 클래스, 복사(copyWith), 비교(equatable) 기능을 자동 생성.
  • json_serializable과 함께 사용 가능.

✅ 사용 예시

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user.freezed.dart';
part 'user.g.dart';


class User with _$User {
  const factory User({
    required int id,
    required String name,
  }) = _User;

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

🔧 의존성 추가

dependencies:
  freezed_annotation: ^2.2.0

 dev_dependencies:
  build_runner: ^2.4.0
  freezed: ^2.3.2
  json_serializable: ^6.6.1

⚡ 코드 생성

flutter pub run build_runner build

4️⃣ json_serializable vs freezed 비교

구분json_serializablefreezed
목적JSON 직렬화/역직렬화불변 객체, 데이터 클래스 자동 생성
가독성코드가 단순하고 직관적다양한 기능으로 인해 상대적으로 복잡함
기능JSON 변환에 특화복사, 비교, 패턴 매칭 등 다양한 기능 제공
유지보수간편한 데이터 모델 관리복잡한 로직을 효율적으로 관리 가능
주 사용처단순 데이터 변환이 필요한 경우상태 관리, 복잡한 모델링이 필요한 경우

5️⃣ 결론

  • 간단한 API 통신은 http, 고급 네트워크 처리는 dio 사용.
  • 복잡한 상태 관리나 데이터 처리는 freezed, 단순한 JSON 변환은 json_serializable 사용.
profile
안녕하세요.

0개의 댓글