[Flutter] Http 통신 / Rest API 호출하기 3편 - Get Connect

Tyger·2023년 3월 1일
0

Flutter

목록 보기
27/57

Http 통신 / Rest API 호출하기 3편 - Get Connect

Http 통신 / Rest API 호출하기 1편 - Http
Http 통신 / Rest API 호출하기 2편 - Dio

get | Dart Packages
url_launcher | Flutter Package

Lorem Picsum

지금까지 http와 dio를 사용하여 API 호출을 하는 방법에 대해서 알아보았다.

저는 지금까지 Get 라이브러리에서 API 호출이 가능한지를 모르고 있었다.
이번에 API 호출 방법에 대해서 글을 작성하다가 Get에서도 API 통신을 지원해준다는 것을 알게 되어 Get으로 API 통신을 하는 방법에 대해서 가볍게 살펴보도록 하겠다.

Flutter

Get Connect를 통해서 API 통신을 진행해보자.

dependencies

dependencies:
	get: ^4.6.5

Model

Rest API로 리턴 구조의 객체 모델이다. 이미지를 가져오는 API를 get 방식으로 호출할 것이고, 이미지 id, 작성자, 가로 세로 높이, 이미지 웹 url, 이미지를 다운받을 수 있는 downloadUrl 이렇게 되어 있다.

해당 API 데이터를 가져올 때 json 형태의 구조를 앱에서 사용할 객체로 변환하여야 한다.

class PiscumPhotoModel {
  final String id;
  final String author;
  final int width;
  final int height;
  final String url;
  final String downloadUrl;

  PiscumPhotoModel({
    required this.id,
    required this.author,
    required this.width,
    required this.height,
    required this.url,
    required this.downloadUrl,
  });
}

json을 변환할 때는 아래 두 가지 코드 모두 변환할 수 있는 코드이기에, 편한 방법을 사용하면 된다.

 PiscumPhotoModel.fromJson(Map<String, dynamic> json)
      : id = json["id"],
        author = json["author"],
        width = json["width"],
        height = json["height"],
        url = json["url"],
        downloadUrl = json["download_url"];
factory PiscumPhotoModel.fromJson(Map<String, dynamic> json) {
    return PiscumPhotoModel(
      id: json["id"],
      author: json["author"],
      width: json["width"],
      height: json["height"],
      url: json["url"],
      downloadUrl: json["download_url"],
    );
  }

UI

UI 구조는 이전 글에서 살펴본 구조와 동일하다.

   return GetBuilder<HttpWithGetConnectGetx>(
        init: HttpWithGetConnectGetx()..started(),
        builder: (controller) {
          return Scaffold(
            appBar: appBar(title: "Get Connect"),
            body: ListView.builder(
                controller: controller.scrollController,
                itemCount: controller.photos.length,
                itemBuilder: ((context, index) {
                  return Padding(
                    padding:
                        const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
                    child: Column(
                      children: [
                        SizedBox(
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              SizedBox(
                                width: MediaQuery.of(context).size.width * 0.2,
                                height: MediaQuery.of(context).size.width * 0.2,
                                child: ClipRRect(
                                  borderRadius: BorderRadius.circular(12),
                                  child: Image.network(
                                    controller.photos[index].downloadUrl,
                                    fit: BoxFit.cover,
                                    frameBuilder: (BuildContext context,
                                        Widget child,
                                        int? frame,
                                        bool wasSynchronouslyLoaded) {
                                      return Container(
                                        decoration: BoxDecoration(
                                          borderRadius:
                                              BorderRadius.circular(12),
                                          color: const Color.fromRGBO(
                                              91, 91, 91, 1),
                                        ),
                                        child: child,
                                      );
                                    },
                                    loadingBuilder: (BuildContext context,
                                        Widget child,
                                        ImageChunkEvent? loadingProgress) {
                                      if (loadingProgress == null) {
                                        return child;
                                      }
                                      return Container(
                                        decoration: BoxDecoration(
                                          borderRadius:
                                              BorderRadius.circular(12),
                                          color: const Color.fromRGBO(
                                              91, 91, 91, 1),
                                        ),
                                        child: const Center(
                                          child: CircularProgressIndicator(
                                            color: Colors.amber,
                                          ),
                                        ),
                                      );
                                    },
                                  ),
                                ),
                              ),
                              const SizedBox(width: 12),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  _content(
                                      url: controller.photos[index].url,
                                      title: "ID : ",
                                      content: controller.photos[index].id),
                                  _content(
                                      url: controller.photos[index].url,
                                      title: "Author : ",
                                      content: controller.photos[index].author),
                                  _content(
                                      url: controller.photos[index].url,
                                      title: "Width : ",
                                      content:
                                          "${controller.photos[index].width}"),
                                  _content(
                                      url: controller.photos[index].url,
                                      title: "Height : ",
                                      content:
                                          "${controller.photos[index].height}"),
                                ],
                              )
                            ],
                          ),
                        ),
                        if (controller.photos.length - 1 == index &&
                            controller.isAdd) ...[
                          const SizedBox(
                            height: 100,
                            child: Center(
                                child: CircularProgressIndicator(
                              color: Colors.deepOrange,
                            )),
                          ),
                        ],
                      ],
                    ),
                  );
                })),
          );
        });
  }
  GestureDetector _content({
    required String title,
    required String content,
    required String url,
  }) {
    return GestureDetector(
      onTap: () async {
        if (await canLaunchUrlString(url)) {
          await launchUrlString(url, mode: LaunchMode.externalApplication);
        }
      },
      child: Row(
        children: [
          Text(
            title,
            style: const TextStyle(
              fontSize: 14,
              fontWeight: FontWeight.bold,
            ),
          ),
          Text(
            content,
            style: const TextStyle(
                fontSize: 14, color: Color.fromRGBO(215, 215, 215, 1)),
          ),
        ],
      ),
    );
  }

GetxController

이전 시간에 구현한 GetxController와 동일하게 개발해서 Get Connect에 대해서만 살펴보도록 하겠다.

GetConnect 객체를 선언해주자.

final GetConnect _getConnect = GetConnect();

Get에서 API호출을 하는 기능으로 GetConnect가 있는데, 사용 방법은 거의 Dio 라이브러리와 동일하다고 봐도 된다.

  Future<List<PiscumPhotoModel>> _fetchPost({
    required int pageNo,
  }) async {
    try {
      final _response = await _getConnect
          .get("https://picsum.photos/v2/list?page=$pageNo&limit=10");
      if (_response.statusCode == 200) {
        List<dynamic> _data = _response.body as List<dynamic>;
        List<PiscumPhotoModel> _result =
            _data.map((e) => PiscumPhotoModel.fromJson(e)).toList();
        return _result;
      } else {
        return [];
      }
    } catch (error) {
      logger.e(error);
      return [];
    }
  }

Result

Git

https://github.com/boglbbogl/flutter_velog_sample/tree/main/lib/http/get_connect

마무리

이렇게 해서 Flutter에서 Http 통신, Rest API를 사용할 수 있도록 제공하고 있는 라이브러리인 http, Dio, GetConnect에 대해서 살펴보았다.

세가지 방식 중 저는 http 라이브러리를 가장 선호하고 있어, 앞으로도 글을 작성할 때 예제 코드에 http를 주로 사용할 것 같다.

profile
Flutter Developer

0개의 댓글