REST API는 현대 애플리케이션에서 서버와 클라이언트 간의 데이터를 주고받는 중요한 방법입니다. Flutter에서도 REST API를 통합하여 서버와 데이터를 주고받을 수 있으며, 이를 통해 앱의 기능성을 확장할 수 있습니다. 이번 글에서는 Flutter에서 REST API를 사용하는 방법을 단계별로 설명하고, 데이터를 가져오거나 전송하는 다양한 HTTP 요청(GET, POST, PUT, DELETE)을 처리하는 방법을 다룹니다.
1. REST API란?
REST(Representational State Transfer)는 네트워크 상에서 클라이언트와 서버 간에 데이터를 주고받는 방식 중 하나입니다. 주로 HTTP 메서드(GET, POST, PUT, DELETE)를 사용하여 데이터를 요청하거나 수정하고, 서버에서는 JSON 또는 XML 형식으로 데이터를 반환합니다. REST API는 유연하고 확장 가능하며, 대부분의 현대 웹 및 모바일 애플리케이션에서 사용됩니다.
2. Flutter에서 REST API 통합하기
Flutter에서 REST API를 사용하기 위해 http 패키지를 사용합니다. 이 패키지는 다양한 HTTP 요청을 처리할 수 있으며, 쉽게 데이터를 서버와 주고받을 수 있습니다.
2.1 http 패키지 설치
먼저, pubspec.yaml 파일에 http 패키지를 추가해야 합니다.
dependencies:
http: ^0.13.3
그리고 flutter pub get 명령어를 실행하여 패키지를 다운로드합니다.
2.2 http 패키지 임포트
http 패키지를 사용하려면, 아래와 같이 import 문을 추가해야 합니다.
import 'package:http/http.dart' as http;
import 'dart:convert';
dart:convert는 JSON 형식의 데이터를 디코딩하고 인코딩하는 데 사용됩니다.
3. GET 요청: 데이터 가져오기
GET 요청은 클라이언트가 서버에서 데이터를 요청할 때 사용됩니다. 예를 들어, 뉴스 기사 목록을 가져오거나 사용자 정보를 받아오는 작업에서 사용됩니다.
3.1 GET 요청 예제
다음은 REST API를 사용하여 JSON 형식의 데이터를 받아오는 예제입니다.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State {
late Future<list> _users;
@override
void initState() {
super.initState();
_users = fetchUsers();
}
Future<list> fetchUsers() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to load users');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('REST API GET Example')),
body: FutureBuilder<list>(
future: _users,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data![index]['name']),
subtitle: Text(snapshot.data![index]['email']),
);
},
);
} else {
return Center(child: Text('No data available'));
}
},
),
);
}
}
</list</list</list
- http.get: GET 요청을 통해 API로부터 데이터를 받아옵니다.
- FutureBuilder: 비동기 데이터를 처리하기 위해 사용하며, 로딩 상태, 성공 또는 실패 시 각각 적절한 UI를 보여줍니다.
- JSON 디코딩: jsonDecode를 사용하여 JSON 형식의 응답을 Flutter에서 사용할 수 있는 Dart 객체로 변환합니다.
4. POST 요청: 데이터 전송
POST 요청은 서버로 데이터를 전송하거나 새 리소스를 생성할 때 사용됩니다. 예를 들어, 사용자가 입력한 데이터를 서버에 전송하여 저장하거나, 새로운 게시글을 작성하는 경우에 사용됩니다.
4.1 POST 요청 예제
다음 예제는 사용자 정보를 서버로 전송하는 POST 요청을 처리하는 방법을 보여줍니다.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: PostDataScreen(),
);
}
}
class PostDataScreen extends StatefulWidget {
@override
_PostDataScreenState createState() => _PostDataScreenState();
}
class _PostDataScreenState extends State {
final TextEditingController _nameController = TextEditingController();
final TextEditingController _jobController = TextEditingController();
Future _submitData(String name, String job) async {
final response = await http.post(
Uri.parse('https://reqres.in/api/users'),
headers: <string, string="">{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<string, string="">{
'name': name,
'job': job,
}),
);
if (response.statusCode == 201) {
print('Data submitted successfully');
print('Response: ${response.body}');
} else {
throw Exception('Failed to submit data');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('REST API POST Example')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: _nameController,
decoration: InputDecoration(labelText: 'Name'),
),
TextField(
controller: _jobController,
decoration: InputDecoration(labelText: 'Job'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
_submitData(_nameController.text, _jobController.text);
},
child: Text('Submit'),
),
],
),
),
);
}
}
</string,></string,>
- http.post: POST 요청을 통해 서버로 데이터를 전송합니다.
- 헤더 설정: Content-Type을 application/json으로 지정하여 JSON 형식의 데이터를 서버로 보냅니다.
- JSON 인코딩: jsonEncode를 사용하여 데이터를 JSON 형식으로 변환하여 서버로 전송합니다.
5. PUT 요청: 데이터 수정
PUT 요청은 서버의 기존 데이터를 업데이트할 때 사용됩니다. 특정 리소스의 정보를 수정할 때 주로 사용됩니다.
5.1 PUT 요청 예제
Future updateUser(String id, String name, String job) async {
final response = await http.put(
Uri.parse('https://reqres.in/api/users/$id'),
headers: <string, string="">{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<string, string="">{
'name': name,
'job': job,
}),
);
if (response.statusCode == 200) {
print('User updated successfully');
} else {
throw Exception('Failed to update user');
}
}
</string,></string,>
위 예제에서는 서버의 특정 사용자의 정보를 업데이트합니다.
6. DELETE 요청: 데이터 삭제
DELETE 요청은 서버에서 데이터를 삭제할 때 사용됩니다.
6.1 DELETE 요청 예제
Future deleteUser(String id) async {
final response = await http.delete(
Uri.parse('https://reqres.in/api/users/$id'),
);
if (response.statusCode == 204) {
print('User deleted successfully');
} else {
throw Exception('Failed to delete user');
}
}
이 코드는 서버에서 사용자의 데이터를 삭제하는 DELETE 요청의 예시입니다.
7. 오류 처리 및 예외 처리
REST API 통신 중 오류가 발생할 수 있습니다. HTTP 요청이 실패했을 때 예외 처리를 통해 안정적인 사용자 경험을 제공하는 것이 중요합니다.
7.1 오류 처리 예제
Future fetchData() async {
try {
final response = await http.get(Uri.parse('https://example.com/data'));
if (response.statusCode == 200) {
// 데이터 처리
} else {
throw Exception('Failed to load data');
}
} catch (error) {
print('Error occurred: $error');
}
}
위 코드는 HTTP 요청 중 발생하는 오류를 `try-c
atch` 블록으로 처리하여, 오류가 발생했을 때 예외를 발생시키고 처리하는 방법을 보여줍니다.
8. 비동기 처리 및 FutureBuilder 사용
Flutter에서 HTTP 요청은 비동기적으로 처리되므로, async와 await 키워드를 사용하여 API 요청을 비동기 처리해야 합니다. 또한, FutureBuilder를 사용하여 비동기 데이터 로딩 상태를 UI에 반영할 수 있습니다.
8.1 FutureBuilder 사용 예제
FutureBuilder(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Text('Data: ${snapshot.data}');
}
},
);
FutureBuilder는 비동기 데이터를 UI에 반영하기 위해 자주 사용되는 위젯입니다.
결론
Flutter에서 REST API를 사용하는 것은 매우 간단하고 직관적입니다. http 패키지를 사용하여 GET, POST, PUT, DELETE 요청을 통해 데이터를 주고받을 수 있으며, 비동기적으로 데이터를 처리할 수 있습니다. 이번 글에서 설명한 방법을 활용하여 Flutter 애플리케이션에서 REST API와의 통신을 쉽게 구현해보세요. REST API를 통해 다양한 외부 서비스와 상호작용하는 앱을 만들 수 있습니다.
'Flutter' 카테고리의 다른 글
Flutter의 데이터 바인딩(Data Binding) 사용법 (0) | 2025.03.16 |
---|---|
Flutter의 데이터 모델링(Data Modeling) 사용법 (1) | 2025.03.16 |
Flutter의 GraphQL 사용법 (0) | 2025.03.15 |
Flutter의 API 통합(API Integration) 사용법 (0) | 2025.03.15 |
Flutter의 데이터 동기화(Data Synchronization) 사용법 (0) | 2025.01.28 |