작성자: 당신의 이름 | 날짜: 2023년 10월
소개
플러터(Flutter)는 구글이 개발한 오픈 소스 UI 소프트웨어 개발 키트(SDK)로,
단일 코드 베이스를 통해 여러 플랫폼에서 작동하는 애플리케이션을 빠르게 구축할 수 있습니다.
이번 강좌에서는 플러터에서 외부 API와 통신할 때 흔히 사용하는 http
패키지에 대해 살펴보겠습니다.
이 패키지는 RESTful API와의 통신을 간편하게 할 수 있는 도구입니다.
http 패키지 설치
http 패키지를 사용하기 위해, 먼저 pubspec.yaml
파일에 해당 패키지를 추가해야 합니다.
아래 코드를 dependencies:
섹션에 추가하세요:
dependencies:
http: ^0.13.4
패키지를 추가한 후, 아래의 명령어를 사용하여 패키지를 설치합니다:
flutter pub get
기본 사용법
http 패키지를 사용하기 위해서는 먼저 관련된 클래스를 import해야 합니다.
다음과 같이 코드를 작성하여 http 패키지를 사용합니다:
import 'package:http/http.dart' as http;
이제 외부 API에 GET 요청을 보내는 방법을 살펴보겠습니다.
예를 들어, JSONPlaceholder API에서 사용자 정보를 받아오는 예제를 보겠습니다:
Future fetchData() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (response.statusCode == 200) {
// 요청이 성공적으로 끝났을 때
print('데이터: ${response.body}');
} else {
// 요청이 실패했을 때
throw Exception('데이터를 가져오는 데 실패했습니다.');
}
}
위의 함수는 비동기적으로 작동하며,
API로부터 사용자 정보를 요청하고, 응답이 성공적이면 해당 데이터를 출력합니다.
POST 요청 보내기
이제 POST 요청을 보내는 방법에 대해 알아보겠습니다.
예를 들어, 새로운 사용자를 생성하는 API에 데이터를 보내는 경우를 살펴보겠습니다:
Future createUser() async {
final response = await http.post(
Uri.parse('https://jsonplaceholder.typicode.com/users'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode({
'name': '홍길동',
'username': 'honggildong',
'email': 'gildong@example.com',
}),
);
if (response.statusCode == 201) {
// 사용자가 성공적으로 생성되었습니다.
print('사용자 생성됨: ${response.body}');
} else {
// 요청이 실패했을 때
throw Exception('사용자 생성 실패');
}
}
위의 코드에서 `jsonEncode` 함수는 Dart의 내장 JSON 인코딩 함수로,
Dart 객체를 JSON 형식의 문자열로 변환하는 데 사용됩니다.
쿼리 파라미터와 헤더
HTTP GET 요청에서 쿼리 파라미터를 추가하고
요청 헤더를 설정하는 방법에 대해 알아보겠습니다.
예를 들어, 특정 조건에 따라 데이터를 필터링 할 수 있습니다:
Future fetchFilteredData() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users?filter=active'),
headers: {
'Authorization': 'Bearer some_api_key',
}
);
if (response.statusCode == 200) {
print('필터링된 데이터: ${response.body}');
} else {
throw Exception('필터링된 데이터를 가져오는 데 실패했습니다.');
}
}
여기서 `filter=active`는 API에서 제공하는 쿼리 파라미터이고,
`Authorization` 헤더는 API 키를 포함하여 서버에 인증 정보를 제공하는 방법입니다.
error handling (오류 처리)
API 요청을 할 때는 항상 오류를 처리해야 합니다.
HTTP 요청의 상태 코드와 예외 상황에 대한 처리를 통해
사용자에게 더 나은 경험을 제공할 수 있습니다:
Future fetchDataWithErrorHandling() async {
try {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (response.statusCode == 200) {
print('데이터: ${response.body}');
} else {
throw Exception('서버에서 오류 발생: ${response.statusCode}');
}
} catch (e) {
print('요청 중 오류 발생: $e');
}
}
위의 코드에서는 try-catch 문을 사용하여
비동기 요청 중 발생할 수 있는 예외를 처리합니다.
HTTP 클라이언트의 재사용
HTTP 클라이언트를 재사용하여 성능을 최적화하고
여러 요청에서 공통적으로 사용할 수 있습니다.
다음과 같이 HTTP 클라이언트를 만들 수 있습니다:
class ApiService {
final http.Client client;
ApiService(this.client);
Future fetchData() async {
final response = await client.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
// 위와 동일한 데이터 처리 로직...
}
}
// 사용 예:
final apiService = ApiService(http.Client());
await apiService.fetchData();
이처럼 클라이언트를 클래스에 주입하여,
재사용성과 테스트 용이성을 높일 수 있습니다.
JSON 데이터 구문 분석
API에서 받은 JSON 데이터를 구문 분석하여 사용할 수 있습니다.
데이터를 내부적으로 소비하기 위해 모델 클래스를 만드는 것이 일반적입니다:
class User {
final int id;
final String name;
final String username;
final String email;
User({required this.id, required this.name, required this.username, required this.email});
factory User.fromJson(Map json) {
return User(
id: json['id'],
name: json['name'],
username: json['username'],
email: json['email'],
);
}
}
위의 모델 클래스를 사용하여
JSON 데이터를 객체로 변환하는 방법을 보여줍니다.
리스트 데이터 처리
여러 개의 JSON 객체를 리스트로 처리하는 방법을 알아보겠습니다.
이를 위해, API로부터 받은 데이터를 적절히 변환해야 합니다:
Future> fetchUsers() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (response.statusCode == 200) {
List jsonData = jsonDecode(response.body);
return jsonData.map((data) => User.fromJson(data)).toList();
} else {
throw Exception('사용자 목록을 가져오는 데 실패했습니다.');
}
}
이 코드는 서버에서 응답받은 JSON 데이터를 파싱하고,
여러 사용자의 정보를 리스트 형식으로 반환합니다.
HTTP 리디렉션 처리
특정 API 요청은 리디렉션을 처리해야 할 수도 있습니다.
이 경우, http.Client
를 사용할 때 자동으로 처리되지만,
직접 리디렉션을 처리하는 방법도 살펴보겠습니다:
Future handleRedirect() async {
final response = await http.get(Uri.parse('https://httpbin.org/redirect/1'));
if (response.statusCode == 200) {
print('최종 URL: ${response.request!.url}');
} else {
print('요청 실패: ${response.statusCode}');
}
}
위의 예제에서는 HTTP 요청에 대해 리디렉션을 자동으로 따라가 최종 URL을 출력하게 됩니다.
종합 예제: CRUD 애플리케이션 만들기
이제까지 배운 내용을 바탕으로, 간단한 CRUD(Create, Read, Update, Delete) 애플리케이션을 구현하는 방법을 논의해 보겠습니다.
예를 들어, JSONPlaceholder API를 사용하여 사용자를 추가/조회/수정/삭제하는 기능을 구현할 수 있습니다.
class UserApiService {
final http.Client client;
UserApiService(this.client);
Future> fetchUsers() async {
// 사용자를 가져오는 코드...
}
Future createUser(User user) async {
// 사용자 생성 코드...
}
Future updateUser(User user) async {
// 사용자 수정 코드...
}
Future deleteUser(int id) async {
final response = await client.delete(Uri.parse('https://jsonplaceholder.typicode.com/users/$id'));
// 삭제 처리 로직...
}
}
위 예제에서는 CRUD 작업을 위한 메서드를 포함하는 `UserApiService` 클래스를 정의합니다.
실제 HTTP 요청을 구현하여 기능을 추가할 수 있습니다.