본문 바로가기
Study/Flutter

[Flutter] Rest Api 호출 라이브러리 비교 (dio,retrofit,chopper)

Flutter에서 가장 많이 사용되는 Rest API 호출 라이브러리 중 상위 랭킹을 확인해보면 다음과 같습니다.

pub.dev에서 라이브러리 다운로드 수와 별점 평가 수 등을 바탕으로 나온 통계입니다.

  1. Dio
  2. http
  3. retrofit
  4. chopper
  5. http_client

이 처럼 Flutter에서 REST API 호출을 위해 사용할 수 있는 다양한 라이브러리가 있습니다.

이 중에서 가장 인기 있는 라이브러리들을 비교해보겠습니다.

 

1. 라이브러리

http 패키지

Flutter의 기본 패키지인 http를 사용하면 간단하게 REST API 호출을 할 수 있습니다. 이 패키지는 Dart 언어 자체의 내장 패키지이며, HTTP 요청 및 응답을 처리하는데 필요한 기능을 제공합니다. 다른 패키지와 비교해서 가볍고 사용하기 간편합니다. 하지만 일부 고급 기능이 부족하다는 단점이 있습니다.

 

dio 패키지

dio는 Flutter에서 가장 인기 있는 HTTP 클라이언트 라이브러리 중 하나입니다. http 패키지보다 많은 고급 기능을 제공하며, Interceptor, FormData, 파일 업로드 등을 지원합니다. 또한, JSON 자동 변환 기능과 취소 기능도 지원하므로 편리하게 사용할 수 있습니다. 다만, 사용하기에는 상대적으로 복잡합니다.

 

retrofit 패키지

retrofit은 Android에서 인기 있는 라이브러리인 Retrofit을 Flutter에서 사용할 수 있게 만든 패키지입니다. Retrofit과 유사한 형태로 작성할 수 있어 개발자들이 익숙해지기 쉽습니다. 자동 JSON 변환과 같은 다양한 기능을 제공하며, dio와 유사한 성능을 가지고 있습니다. 하지만, Flutter에서만 사용 가능하므로 Android나 iOS에서 사용할 수 없습니다.

 

chopper 패키지

chopper는 Retrofit에서 영감을 받은 Flutter용 REST API 호출 라이브러리입니다. Dio 기반으로 작성되어 있으며, 편리한 인터셉터와 JSON 직렬화를 지원합니다. 또한, API 요청과 응답에 대한 캐싱 기능도 제공합니다. 사용하기 쉽고 성능이 뛰어나며, 코드가 간결해 유지 보수성이 높습니다.

각 라이브러리는 각각의 특징을 가지고 있으므로, 사용하고자 하는 기능에 따라 선택하면 됩니다. 단순한 요청만 필요한 경우 http 패키지를 사용하면 되고, 고급 기능이 필요한 경우에는 dio, retrofit, chopper 등의 패키지를 선택할 수 있습니다.

 

2. 예제코드

각 라이브러리의 사용 코드를 예제와 함께 설명해드리겠습니다.

공통적으로 호출한 객체는 아래와 같이 get으로 받아올 Todo(할일) , post로 저장할 Post(게시글) 입니다.

class Todo {
  final int userId;
  final int id;
  final String title;
  final bool completed;

  Todo({required this.userId, required this.id, required this.title, required this.completed});

  factory Todo.fromJson(Map<String, dynamic> json) {
    return Todo(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
      completed: json['completed'],
    );
  }
}

class Post {
  final int id;
  final String title;
  final String body;
  final int userId;

  Post({required this.id, required this.title, required this.body, required this.userId});

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      id: json['id'],
      title: json['title'],
      body: json['body'],
      userId: json['userId'],
    );
  }
}

 

 

  1. http 패키지

import 'package:http/http.dart' as http;

// GET 요청
var response = await http.get(Uri.parse('<https://jsonplaceholder.typicode.com/todos/1>'));
print(response.body);

// POST 요청
var url = Uri.parse('<https://jsonplaceholder.typicode.com/posts>');
var response = await http.post(url, body: {'title': 'foo', 'body': 'bar', 'userId': '1'});
print(response.statusCode);

http 패키지는 기본적으로 Dart에서 제공하는 내장 패키지이므로,

import 구문을 통해 바로 사용할 수 있습니다.

GET 요청과 POST 요청을 모두 처리할 수 있으며, 간단하고 직관적인 사용법을 가지고 있습니다.

 

   2. dio 패키지

import 'package:dio/dio.dart';

// GET 요청
var dio = Dio();
var response = await dio.get('<https://jsonplaceholder.typicode.com/todos/1>');
print(response.data);

// POST 요청
var dio = Dio();
var response = await dio.post('<https://jsonplaceholder.typicode.com/posts>', data: {'title': 'foo', 'body': 'bar', 'userId': '1'});
print(response.statusCode);

dio 패키지는 간단한 GET/POST 요청부터 다양한 고급 기능까지 제공합니다.

이를 사용하기 위해서는 Dio 인스턴스를 생성하고, get/post 메소드를 사용하여 요청을 보내면 됩니다.

기본적으로 JSON 형식으로 데이터를 주고 받으며, Interceptor와 FormData 등의 고급 기능을 지원합니다.

 

   3. retrofit 패키지

import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';

part 'my_api.g.dart';

@RestApi(baseUrl: '<https://jsonplaceholder.typicode.com>')
abstract class MyApi {
  factory MyApi(Dio dio) = _MyApi;

  @GET('/todos/{id}')
  Future getTodoById(@Path('id') int id);

  @POST('/posts')
  Future createPost(@Body() Map<string, dynamic=""> data);
}

// Retrofit 생성
var dio = Dio();
var myApi = MyApi(dio);

// GET 요청
var todo = await myApi.getTodoById(1);
print(todo.title);

// POST 요청
var post = await myApi.createPost({'title': 'foo', 'body': 'bar', 'userId': '1'});
print(post.id);

retrofit 패키지는 안드로이드의 Retrofit과 유사한 형태로 작성할 수 있으며, API 요청을 인터페이스로 정의합니다.

이를 사용하기 위해서는 먼저 인터페이스를 정의하고, Retrofit 생성자를 호출하여 인스턴스를 생성합니다.

그 후, 인터페이스에서 정의한 메소드를 호출하면 됩니다.

 

  4. chopper 패키지

import 'package:chopper/chopper.dart';

part 'my_api.chopper.dart';

@ChopperApi(baseUrl: '<https://jsonplaceholder.typicode.com>')
abstract class MyApi extends ChopperService {
  static MyApi create([ChopperClient? client]) => _$MyApi(client);

  @Get(path: '/todos/{id}')
  Future<response> getTodoById(@Path() int id);

  @Post(path: '/posts')
  Future<response> createPost(@Body() Map<string, dynamic=""> data);
}

// Chopper 생성
var chopper = ChopperClient(
  baseUrl: '<https://jsonplaceholder.typicode.com>',
  services: [
    MyApi.create(),
  ],
);

// GET 요청
var response = await chopper.get('/todos/1');
print(response.body?.title);

// POST 요청
var response = await chopper.post('/posts', body: {'title': 'foo', 'body': 'bar', 'userId': '1'});
print(response.body?.id);
</string,></response</response

chopper 패키지는 Retrofit과 유사한 형태로 작성할 수 있으며,

인터페이스 대신에 ChopperService를 상속받아 API 요청을 정의합니다.

이를 사용하기 위해서는 먼저 ChopperClient 인스턴스를 생성하고, ChopperService를 구현한 클래스를 services에 등록합니다.

그 후, ChopperClient 인스턴스를 사용하여 요청을 보내면 됩니다.

 

  5. http_client 패키지

import 'package:http_client/http_client.dart';

// HTTPClient 생성
var client = HttpClient('<https://jsonplaceholder.typicode.com>');

// GET 요청
var response = await client.get('/todos/1');
print(response.body);

// POST 요청
var response = await client.post('/posts', body: {'title': 'foo', 'body': 'bar', 'userId': '1'});
print(response.statusCode);

http_client 패키지는 간단하고 직관적인 사용법을 가지고 있으며, HTTPClient 클래스를 사용하여 요청을 보냅니다.

HTTPClient 생성자를 통해 base URL을 지정하고, get/post 메소드를 사용하여 요청을 보냅니다.

이 패키지는 기본적으로 Dart의 내장 http 패키지를 기반으로 하고 있습니다.

 

 

다음번에는 가장 많이 사용되어지는 dio 라이브러리를 이용해

Interceptor, FormData, 파일 업로드 등의 고급 기능을 사용해보며,

추가적으로 사용자인증에 많이사용되는 Json Token을 다루는것까지 정리해보겠습니다.