Flutter에서 Retrofit은 네트워크 요청을 간편하고 효율적으로 처리할 수 있는 강력한 HTTP 클라이언트 라이브러리입니다. Retrofit은 Dart와 Flutter에서 주로 사용되며, 코드를 간결하고 유지 보수하기 쉽게 만들어줍니다. 이번 글에서는 Flutter에서 Retrofit을 사용하는 방법과 이를 구현하는 예제를 자세히 살펴보겠습니다.
1. Retrofit 패키지 설치
먼저, retrofit, dio, 그리고 json_annotation 패키지를 pubspec.yaml 파일에 추가합니다.
dependencies:
flutter:
sdk: flutter
dio: ^5.0.0
retrofit: ^3.0.1
json_annotation: ^4.5.0
dev_dependencies:
build_runner: ^2.1.7
retrofit_generator: ^3.0.1
json_serializable: ^6.2.0
그리고 pub get 명령어를 실행하여 패키지를 설치합니다.
2. Retrofit 설정
Retrofit을 사용하려면 API 인터페이스를 정의하고, 이를 통해 네트워크 요청을 처리합니다.
Step 1: API 인터페이스 정의
먼저, API 인터페이스를 정의합니다. 여기에 Retrofit 어노테이션을 사용하여 HTTP 메서드와 엔드포인트를 지정합니다.
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
import 'package:json_annotation/json_annotation.dart';
part 'api_service.g.dart';
@RestApi(baseUrl: "https://jsonplaceholder.typicode.com/")
abstract class ApiService {
factory ApiService(Dio dio, {String baseUrl}) = _ApiService;
@GET("/posts/{id}")
Future<Post> getPost(@Path("id") int id);
@POST("/posts")
Future<Post> createPost(@Body() Post post);
}
@JsonSerializable()
class Post {
int userId;
int id;
String title;
String body;
Post({required this.userId, required this.id, required this.title, required this.body});
factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
Map<String, dynamic> toJson() => _$PostToJson(this);
}
위 코드는 ApiService 인터페이스와 Post 모델을 정의합니다. @RestApi 어노테이션으로 기본 URL을 설정하고, HTTP 메서드와 엔드포인트를 지정합니다. Post 클래스는 JSON 직렬화를 위해 json_annotation을 사용합니다.
Step 2: 코드 생성
다음 명령어를 실행하여 Retrofit과 JSON 직렬화 코드를 생성합니다.
flutter pub run build_runner build
이 명령어는 api_service.g.dart 파일을 생성하여 Retrofit과 JSON 직렬화 코드를 자동으로 생성합니다.
3. Retrofit 사용하기
이제 생성된 코드를 사용하여 Retrofit을 통해 네트워크 요청을 보낼 수 있습니다.
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'api_service.dart';
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<HomeScreen> {
late ApiService apiService;
String data = "Loading...";
@override
void initState() {
super.initState();
final dio = Dio();
apiService = ApiService(dio);
fetchPost();
}
Future<void> fetchPost() async {
try {
final post = await apiService.getPost(1);
setState(() {
data = post.title;
});
} catch (e) {
setState(() {
data = "Failed to load data: $e";
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Retrofit Example')),
body: Center(
child: Text(data),
),
);
}
}
위 코드는 Retrofit을 사용하여 API에서 데이터를 가져오는 예제입니다. Dio 인스턴스를 생성하고, 이를 사용하여 ApiService를 초기화합니다. fetchPost 메서드는 getPost 메서드를 호출하여 데이터를 가져오고, 응답을 처리하여 화면에 표시합니다.
4. POST 요청 보내기
POST 요청을 보내는 방법도 간단합니다. 다음은 POST 요청을 보내는 예제입니다.
class PostScreen extends StatefulWidget {
@override
_PostScreenState createState() => _PostScreenState();
}
class _PostScreenState extends State<PostScreen> {
late ApiService apiService;
String responseMessage = "";
final TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
final dio = Dio();
apiService = ApiService(dio);
}
Future<void> createPost(String title) async {
final post = Post(userId: 1, id: 0, title: title, body: "Sample body");
try {
final createdPost = await apiService.createPost(post);
setState(() {
responseMessage = "Post created with ID: ${createdPost.id}";
});
} catch (e) {
setState(() {
responseMessage = "Failed to create post: $e";
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Create Post')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(labelText: 'Enter title'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
createPost(_controller.text);
},
child: Text('Create Post'),
),
SizedBox(height: 20),
Text(responseMessage),
],
),
),
),
);
}
}
위 코드는 사용자가 입력한 데이터를 POST 요청으로 서버에 보내는 예제입니다. createPost 메서드는 ApiService의 createPost 메서드를 호출하여 데이터를 전송하고, 응답을 처리하여 결과를 화면에 표시합니다.
5. 에러 처리
HTTP 요청을 보낼 때 발생할 수 있는 다양한 에러를 처리하는 것이 중요합니다. DioError를 통해 에러를 처리할 수 있습니다.
Future<void> fetchPost() async {
try {
final post = await apiService.getPost(1);
setState(() {
data = post.title;
});
} on DioError catch (e) {
if (e.response != null) {
setState(() {
data = "Failed to load data: ${e.response?.statusCode}";
});
} else {
setState(() {
data = "Failed to load data: ${e.message}";
});
}
}
}
위 코드는 DioError를 사용하여 네트워크 요청 시 발생할 수 있는 에러를 처리하는 예제입니다. 에러가 발생하면 적절한 메시지를 사용자에게 표시합니다.
결론
Flutter에서 Retrofit을 사용하면 HTTP 요청을 간편하고 효율적으로 처리할 수 있습니다. Retrofit은 코드의 가독성과 유지 보수성을 높여주며, 강력한 기능을 제공하여 다양한 네트워크 요청을 처리할 수 있습니다. 이번 글에서 소개한 방법들을 활용하여 Flutter 애플리케이션에서 Retrofit을 효율적으로 사용해보세요.
'Flutter' 카테고리의 다른 글
Flutter의 XML 데이터 파싱 (0) | 2024.07.30 |
---|---|
Flutter의 JSON 데이터 파싱 (1) | 2024.07.30 |
Flutter의 Dio 라이브러리 사용법 (29) | 2024.07.29 |
Flutter에서 HTTP 요청 보내기 (1) | 2024.07.29 |
Flutter의 MVVM 패턴 사용법 (0) | 2024.07.29 |