[Flutter] Retrofit 적용해서 api 호출하기

     

 

안드로이드를 개발해본 사람이라면 Retrofit이 친숙할 겁니다. 초창기 restapi를 호출하기 위해 삽질하다가 이제 거의 모든 restapi호출이 retrofit을 사용하는 것으로 통일되고 있는 추세인데요 ㅋㅋ

 

flutter에서 restapi를 어떻게 처리할까 찾아보다가 retrofit for dart가 있어서 해보려고 합니다 ㅋㅋ 역시 쓰던거 하는 게 편하니까~

 

일단 필요한 패키지를 설치합니다. 

 

dependencies:
  retrofit: any
  logger: any  #for logging purpose

dev_dependencies:
  retrofit_generator: any
  build_runner: any

 

flutter pub get을 이용해 설치합시다~

 

이제 바로 api를 호출하는 코드를 만들어볼거에요.

원래 covid19 모니터링하는 거 get으로 호출하는 게 있었는데 그걸 retrofit으로 바꿔보겠습니다.

 

// 기존 소스
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;

class BaseNetwork {
  static final String baseUrl = "https://covid19.mathdro.id/api";

  static Future<Map<String, dynamic>> get(String partUrl) async{
    final fullUrl = baseUrl + "/" + partUrl;
    final response = await http.get(Uri.parse(fullUrl));
    return _processResponse(response);
  }

  static Future<Map<String, dynamic>> _processResponse( http.Response response) async {
    final body = response.body ?? "";

    if (body.isNotEmpty) {
      final jsonBody = json.decode(body);
      return jsonBody;
    }else{
      print("processResponse error");
      return {"error":true};
    }
  }
}

 

위에 쌩 http로 짠 BaseNetwork.dart.

아래가 redrofit으로 짠 retrofit_network.dart

 

import 'package:getxtutorial/src/model/global_entity.dart';
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
part 'retrofit_network.g.dart';

@RestApi(baseUrl: "https://covid19.mathdro.id/api")
abstract class RestClient {
  factory RestClient(Dio dio, {String baseUrl}) = _RestClient;

  @GET("")
  Future<GlobalEntity> getGlobal();
}

아주 싼 간단해졌죠?

 

그럼 controller에서는 어떻게 바뀌었을까?

 

import 'package:get/get.dart';
import 'package:getxtutorial/src/model/global_entity.dart';
import 'package:getxtutorial/src/network/retrofit_network.dart';
import 'package:intl/intl.dart';
import 'package:dio/dio.dart';

import '../network/covid_data_source.dart';

class GlobalController extends GetxController{
  var globalEntity = GlobalEntity().obs;
  final dio = Dio();

  @override
  void onInit() {
    print("GlobalController - onInit");
    // _fetchGlobalData();
    super.onInit();
  }

  fetch() => _fetchGlobalData();

  void _fetchGlobalData() async {
    try {
      // var data = await CovidDataSource.loadGlobalData();
      // globalEntity.value = GlobalEntity.fromJson(data);
      final client = RestClient(dio);
      client.getGlobal().then((value) => globalEntity.value = value);
    }catch(_) {
      print('GlobalController - _fetchGlobalData error');
    }
  }
}

 

실제로 바뀐 부분은 _fetchGlobalData() 안에 있는 client.getGlobal(). then((value) => globalEntity.value = value); 부분이다.

 

RestClient를 만든 다음에 dio 객체를 넣고 retrofit annotation을 추가한 메서드를 실행하면 된다. 그다음 처리는. then으로 끝.

 

사용은 사실 기존 거랑 변함이 없다. 그냥 콜 하는 함수만 바꿔준 거니까 ㅋㅋ

 

 

 

결론적으로 간단해지는 부분은 Network 구현 부분인데 model만 잘 만들면 annotation하나로 그냥 간단하게 데이터를 읽어올 수 있다.

 

 

 

 

 

 

 

반응형

댓글

Designed by JB FACTORY