자라나라
[Flutter] JSON을 이용한 API 통신 본문
kakao developers에서 제공하는 다음(Daum) 책검색 API를 이용하여 간단한 플러터 앱을 만들어 보았다.
(DOIT 플러터앱 프로그래밍 책을 참고 하였다.)
우선 JSON 데이터가 어떻게 디코딩 되는지 간단히 알아보자.
import 'dart:convert';
void main() {
var jsonData = '''
[
{"userName" : "Ray"},
{"age" : 23}
]
''';
var decodedList = json.decode(jsonData);
print(decodedList is List); // true
print(decodedList); // [{userName: Ray}, {age: 23}]
var first = decodedList[0];
var second = decodedList[1];
print(first is Map); // true
print(second); //{age: 23}
print(first['userName']); // Ray
print(second['age'].toString()); // 23
}
우선 JSON 데이터를 이용하려면 위와 같이 convert 라이브러리를 추가해 주어야한다.
jsonData 안에는 간단한 JSON 형태의 문자열을 저장해주었다.
''' '''로 감싼 것은 여러줄의 문자열을 담기 위해서이다.
convert 라이브러리에 포함된 json.decode() 메서드 안에 jsondata를 넣어주면 dynamic형식의 리스트로 반환해준다.
그리고 리스트의 각 값은 key와 value로 이루어진 Map 형식이다.
++ print할 때 String이 아닌 객체는 toString()을 해주는 것이 원칙이다.
그러나 단일객체는 생략가능하기 때문에 위에서 리스트와 맵이 문제없이 출력된 것.
원래는 print(decodedList.toString()); 등으로 확실히 해주는 게 좋다.
일단은 이렇게 디코딩만 알아두고 넘어가고
이제 책 데이터를 가져오기 전에, 데이터를 받아서 보여줄 앱 화면부터 간단히 만들어 보자.
Stateful Widget으로 만든 후, 디코딩된 데이터를 넣을 리스트 변수를 선언해준다.
initState() 내에서 초기화도 시켜주자


위의 플로팅버튼 onPressed 메서드에서 JSON데이터를 불러올 것이다.

Future<String>을 리턴하므로 onPressed에 async를 줬다.
이제 getJsonData() 를 만들어 보자. 드디어 API를 사용해 볼 때이다.
이를 위해선 http 패키지를 설치해야하며, 아까 언급한 convert 패키지도 불러오자
보통은 포스트맨을 많이들 이용하지만 오늘은 플러터만 이용해서 해볼 것이다.
위 링크로 들어가 애플리케이션을 만들어 앱 키 값을 받는다.
다음으로, 오늘은 책 검색기능을 이용해볼 것이기 때문에
홈페이지 상단에 문서 -> 검색 API 가이드 -> 개발 가이드 ->책 검색 섹션을 보면 된다.

url을 먼저 살펴보자
가이드를 보면 request를 위한 파라미터 사용법이 친절히 나와있다.

다시 우리의 url을 보자
https://dapi.kakao.com/v3/search/book?target=title&query=안녕
요청할도메인 도메인에 요청할 파라미터
target 파라미터에 title을 , query 파라미터에 '안녕'을 전달해 준 것
url 전체를 해석하면
dapi.kakao.com 서버에 있는 v3/search/book에게,
제목에 '안녕'이 포함된 책을 내려달라고 하는 것이다.
물론 이를 http 패키지의 get 메소드에 넣어야 처리가 되는 것!
get 메소드가 요구하는 파라미터는 아래와 같다.
Future<Response> get(Uri url, {Map<String, String>? headers})
입력한 값과 비교해보자
var response = await http.get(Uri.parse(url), headers: {"Authorization": "KakaoAK RESTAPI키"});
REST API 키는 맨 처음 홈페이지에서 어플리케이션을 만들 때 발급받은 키를 넣어주면 된다.
앞에 kakaoAK+띄어쓰기는 꼭 넣어주자
이후엔 http response의 실질적인 데이터를 담고있는 body부분을 디코딩해준다.
그 결과의 document의 데이터(이 또한 가이드에 잘 나와있다.)를 임의의 리스트 변수 result에 담아주고
그 데이터를 전부 처음에 초기화시켜줬던 data 변수에 넣어준다.
이 이후로는 그냥 UI만 그려주면 된다
아래는 전체 코드이다.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HttpApp(),
);
}
}
class HttpApp extends StatefulWidget {
const HttpApp({Key? key}) : super(key: key);
@override
State<HttpApp> createState() => _HttpAppState();
}
class _HttpAppState extends State<HttpApp> {
List? data;
String rami = 'circle';
@override
void initState() {
super.initState();
data = List.empty(growable: true);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BOOK SEARCH'),
centerTitle: true,
),
body: Container(
child: Center(
child: data!.length == 0
? Text(
'데이터가 없습니다.',
style: TextStyle(fontSize: 20),
textAlign: TextAlign.center,
)
: ListView.builder(
itemCount: data!.length,
itemBuilder: (context, index){
return Card(
child: Row(
children: [
Image.network(data![index]['thumbnail'],
height: 100,
width: 100,
fit: BoxFit.contain,
),
Container(
width: MediaQuery.of(context).size.width - 150,
child: Column(
children: [
Text(data![index]['title'].toString(), textAlign: TextAlign.center),
Text('저자 : ${data![index]['authors'].toString()}'),
Text('가격 : ${data![index]['sale_price'].toString()}'),
Text('판매중 : ${data![index]['status'].toString()}'),
],
),
)
],
),
);
})
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
getJsonData();
},
child: Icon(Icons.file_download),
),
);
}
Future<String> getJsonData() async {
var url = 'https://dapi.kakao.com/v3/search/book?target=title&query=안녕';
var response = await http.get(Uri.parse(url), headers: {"Authorization": "KakaoAK API키"});
setState(() {
var dataConvertedToJson = json.decode(response.body);
List result = dataConvertedToJson['documents'];
data!.addAll(result);
});
return 'Successful';
}
}
'Flutter' 카테고리의 다른 글
[Flutter] 데이터 저장 (2) 파일 이용하기 (0) | 2022.09.12 |
---|---|
[Flutter] 데이터 저장 (1) shared_preferences (0) | 2022.09.12 |
[Flutter]Stream (0) | 2022.09.02 |
[Flutter] 회원가입 폼 만들기(2)firebase 유저등록 (0) | 2022.09.02 |
[Flutter] 회원가입 폼 만들기(1)TextFormField validator 사용하기 (0) | 2022.08.27 |