Coram Deo

[Flutter] API 데이터 가져오기 (Data Fetching / fromJson) 본문

Flutter

[Flutter] API 데이터 가져오기 (Data Fetching / fromJson)

탁탁슝 2024. 7. 2. 11:49

Data Fetching 방법

API로부터 오늘의 웹툰을 불러오는 법

* 초기 세팅

  • lib → services 폴더 →  api_service.dart 파일을 만든다.
  • ApiService 클래스를 만든다.
  • baseUrl 에 기본 URL 링크를 넣는다.
  • final String baseUrl = "https://webtoon-crawler.nomadcoders.workers.dev";
  • final String today = "today";
  • getTodaysToons() 라는 메서드를 만든다.
  • baseUrl에 today(=endpoint)를 추가한 URL에서 데이터를 가져온다.
  • 가져온 데이터 리스트를 JSON 데이터로 받는다.

1. API에 데이터를 요청할 수 있어야 함

  • http 패키지를 설치해야 함(pub.dev에서 설치)
    • 패키지 설치 방법
      • command 창에 명령어(flutter pub add http) 적거나
      • pubspec.yaml에 dependencies에 (http:^0.13.5) 복붙해서 저장하기
      • http를 설치하면 많은 메서드를 사용할 수 있음
  • http패키지에 있는 get 함수 사용하여 API에 요청 보내기
    • import 'package:http/http.dart' as http 로 해주기
    • uri 타입을 매개변수로 전달해줘야 함
    • final url = Uri.parse('$baseUrl/$today');
      • 문자열인 uri(예시'https://example.com')를 'Uri' 객체로 변환해줌.
    • http.get(url)
      • get 메소드는 매개변수로 Uri url 이 필요하기 때문에 위에서 Uri.parse()를 해준 것.
    • API 요청 보내기
      • API 요청이 처리되어서 응답을 반환할 때까지 기다리기(비동기 프로그래밍; async programming)
      • API에 요청 보내면, 여러가지 이유(유저의 네트워크 문제, 서버의 메모리 문제)로 인해 처리시간이 오래걸릴 수 있음 → 이럴 경우 dart가 서버가 응답할 때까지 기다리게 하기 위해 await 키워드 사용하기
      • await 함수는 async 함수에서만 사용가능함
      • get은 Future 타입 ! 지금 당장 실행되는 게 아님,  미래에 완료되는 함수 
        • Future<Resonse> get(Uri url, ) 
        • 미래에 완료되었을 때, Response를 반환한다.( Response: 서버의 응답에 대한 정보) 
        • 요청에 대한 응답을 사용하기위해 get의 반환값을 저장하기
          • final response = await http.get(url);
        • 만약 response.statusCode 가 200이라면(=요청이 성공적이었으면) response의 body를 출력하기
          • response의 body에는 서버가 보낸 데이터가 있음  

2. API가 반환한 JSON형식의 데이터를 Flutter와 dart에서 사용가능한 데이터 형식인 class로 변환해야 한다.

  • models 폴더 → webtoon_model.dart 파일 만들기 (여기에 WebtoonModel 클래스 만들기)
  • API로부터 응답받은 데이터는 title, thumb, id 로 이루어져있음 
    • {
      	title:"대학원 탈출일지",
          	thumb: https://shared-comic.pstatic.net/thumb/webtoon/790713/thumbnail/thumbnial_IMAG21_3919364435331003700.jpg
          	id:"790713"
      }
  • webtoon_model.dart에서 WebtoonModel 클래스 만들기
    • title, thumb, id 변수 선언하고 constructor(생성자) 만들기
    • 이때 생성자를 named constructor로 만든다
    • 생성자의 이름은 fromJson으로 한다.
    • Webtoons.fromJson(Map<String, dynamic> json)
      	: title = json['title'],
          	  thumb = json['thumb'],
                id = json['id'];
  • 우리가 응답받은 데이터 response.body는 String임 → 근데 원래 포맷이 String이 아닌 JSON이라 이걸 JSON으로 바꾸고 싶음
    • jsonDecode(response.body) 사용하기
    • 얘의 반환값은 dynamic 이라 우리가 반환값타입을 정해야 함
      • final List<dynamic> webtoons = jsonDecode(response.body);
    • 우리가 가져온 API의 JSON은 많은 object로 이루어진 list 임. 그래서 위에 있는 webtoons의  반환타입을 List로 !
      • [ 
        	{    title:"~~", thumb:"~~", id:"~~"    }, 
            	{    title:"~~", thumb:"~~", id:"~~"    }, 
                {    title:"~~", thumb:"~~", id:"~~"    } ,
                                   ... ,
                {    title:"~~", thumb:"~~", id:"~~"    } 
        ]

지금까지 한 걸 정리하면, API 로 부터 가져온 String 데이터를 jsonDecode를 통해 json으로 바꾸고 그 값은 리스트로 이루어져있고 webtoons라는 변수에 그 값들을 담는다.

  • for문을 이용하여 webtoons의 object를 한개씩 접근한다 !
  • for(var webtoon in webtoons){
    	final toon = WebtoonModel.fromJson(webtoon);
        	print(toon.title);
    }
  • title을 출력하는 대신에 각각의 초기화된 webtoon 객체를 webtoonInstances 리스트에 넣어주고, webtoonInstances를 반환한다.
  • Future<List<WebtoonModel>> getTodaysToons() async {
    	List<WebtoonModel> webtoonInstances = [];
        	final url = Uri.parse('$baseUrl/$today');
            final response = await http.get(url);
            if(response.statusCode == 200){
                final List<dynamic> webtoons = jsonDecode(response.body);
                for(var webtoon in webtoons){
                	webtoonsInstances.add(Webtoons.fromJson(webtoon));
                }
                return webtoonInstances;
            }
            throw Error();
    }

 

 

 

출처:https://nomadcoders.co/flutter-for-beginners/lectures/4162