[flutter] #2 RetroFit - RestAPI endPoint handling

giyeon·2021년 5월 19일
0

flutter-retrofit

목록 보기
2/2
post-thumbnail

이 프로젝트는 Youtube '코드팩토리'의 '[Flutter] Rest API 엔드포인트 따느라 삽질 하셨나요? 제가 도와드릴게요 Retrofit!' 강의를 참고했습니다.


RetrofitScreen.dart

GET API를 설정했던 data를 Screen에 띄워보겠습니다!

Screen을 Stateful class로 만들어볼게요.
먼저 RestClient class를 초기화 해요.
initState 내에서 Dio와 RestClient를 초기화 시켜줘요.
microtask method로 정상적으로 Get이 이루어지는지 간단한 테스트도 진행했어요.

class RetrofitScreen extends StatefulWidget {
  
  _RetrofitScreenState createState() => _RetrofitScreenState();
}

class _RetrofitScreenState extends State<RetrofitScreen> {
  /* RestClient 초기화 */
  RestClient client;

  
  void initState() {
    super.initState();
    /* initState 내부에 초기화를 시켜줘요.
    *  파라미터에 Dio를 넣겠다고 설정헀었죠. 
    *  일단 dio 부터 만들어주고, RestClient에 dio를 파라미터로 넣어줘요. */
    Dio dio = Dio();
    client = RestClient(dio);

    /* initState 내부에서 간단한 테스트가 가능해요. */
    Future.microtask(() async {
      final testGetId = await client.getTopNewsId();
      print(testGetId);
      final testGetDetail = await client.getNewsDetail(id: 27187435);
      print(testGetDetail);
    });
  }

이제 client변수로 RestClient class에 접근이 가능해졌어요.
Scaffold의 body부분에 FutureBuilder로 data를 불러와볼게요.
우선 불러올 news의 id값이 필요하니 getTopNewsId method를 future로 설정해줘요.

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Retro Fit'),
      ),
      body: FutureBuilder(
        future: client.getTopNewsId(),

FutureBuilder의 builder 부분은 간단한 로딩스피너 if문을 추가해줄게요.
snapshot.data는 id값들이 모여있는 List 가 돼요.

        builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
          final ids = snapshot.data;
          // List of id ...

이제 id값들을 이용해서 Get으로 만들어둔 getNewsDetail로 News item들을 불러와볼게요.
각각의 News 들은 ListView.builder로 렌더링이 돼요.

ListView의 itemCount값은 리스트의 크기가 되니까 ids.length가 되겠죠!
itemBuilder 내에서 FutureBuilder를 한번 더 사용해요.

처음 FutureBuilder는 id값들을 불러오고,
이번 FutureBuilder는 불러온 id값들을 사용해서 각각의 News item을 불러와요.

getNewsDetail은 파라미터로 id값이 필요하고 return 값은 News class 였죠.
id값은 ListView의 index를 사용하면 각각의 List의 요소에 접근이 가능하니 id값들이 차례대로 들어가게 돼요.

다시 간단한 로딩스피너 if문을 거치면, FutureBuilder로 가져온 snapshot.data 속에는 News class가 들어있게 돼요.

최후 return 값은 renderNewsCard 라는 Widget이 돼요.

          return ListView.builder(
            itemCount: ids.length,
            itemBuilder: (_, index) {
              return FutureBuilder(
                future: client.getNewsDetail(id: ids[index]),
                builder: (_, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  }
                  // print(snapshot.data);  instance of newses ...
                  return renderNewsCard(news: snapshot.data);
                },
              );
            },
          );

News class를 파라미터로 받는 Widget인 renderNewsCard는 간단하게 News item 이 가지고 있는 id, title, url 들을 Text로 나타내줘요.

  renderNewsCard({ News news}) {
    return Card(
      child: Column(
        children: <Widget>[
          Text(news.id.toString() ?? ''),
          Text(news.title ?? ''),
          Text(news.url ?? ''),
        ],
      ),
    );
  }

끝!

retrofit_screen.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_retrofit_tutorial/rest_client.dart';

class RetrofitScreen extends StatefulWidget {
  
  _RetrofitScreenState createState() => _RetrofitScreenState();
}

class _RetrofitScreenState extends State<RetrofitScreen> {

  RestClient client;

  
  void initState() {
    super.initState();
    
    Dio dio = Dio();
    client = RestClient(dio);
  }

  renderNewsCard({ News news}) {
    return Card(
      child: Column(
        children: <Widget>[
          Text(news.id.toString() ?? ''),
          Text(news.title ?? ''),
          Text(news.url ?? ''),
        ],
      ),
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Retro Fit'),
      ),
      body: FutureBuilder(
        future: client.getTopNewsId(),
        builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
          final ids = snapshot.data;
          // List of id ...
          return ListView.builder(
            itemCount: ids.length,
            itemBuilder: (_, index) {
              return FutureBuilder(
                future: client.getNewsDetail(id: ids[index]),
                builder: (_, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  }
                  // print(snapshot.data);  instance of newses ...
                  return renderNewsCard(news: snapshot.data);
                },
              );
            },
          );
        },
      ),
    );
  }
}

이렇게 RetroFit을 통해 API를 다뤄보고, API를 통해 가져온 data를 screen에 띄워봤어요.
저는 API를 다룰때 상황이 주어지면 RetroFit을 자주이용할 것 같아요. 👀

profile
Web , App developer wannabe 🧑🏻‍💻

0개의 댓글