개발일기
Flutter에서 API 연동 완전 정복: Dio vs http 차이와 실전 구조 예시
뱅우
2025. 6. 5. 09:41
반응형
Flutter 앱을 만들다 보면, 서버와 통신하기 위해 반드시 API 연동을 하게 됩니다.
처음에는 http
패키지를 사용하다가, 점점 Dio로 넘어가는 실무 사례가 많습니다.
이 글에서는 Dio
가 왜 실무에서 더 선호되는지, 그리고 API 구조를 어떻게 구성하면 좋은지 알려드립니다.
🔗 1. http vs Dio: 무엇이 다를까?
항목 | http | Dio |
---|---|---|
패키지 크기 | 가볍고 단순 | 풍부한 기능 포함 |
Interceptor | 별도 구현 필요 | 기본 제공 (토큰 갱신, 로깅 등) |
FormData, 파일 업로드 | 제한적 | 내장 지원 |
에러 핸들링 | try-catch 수동 처리 | Response 타입에 다양한 상태 제공 |
👉 실무에서는 확장성, 유지보수성 측면에서 Dio가 우세합니다.
🧱 2. Dio 설치 및 기본 사용법
// pubspec.yaml
dependencies:
dio: ^5.0.0
import 'package:dio/dio.dart';
final dio = Dio();
void fetchData() async {
try {
final response = await dio.get('https://jsonplaceholder.typicode.com/posts');
print(response.data);
} catch (e) {
print('Error: $e');
}
}
📦 3. 실무에 맞는 API 구조 예시
기능별로 API 호출 로직을 모듈화하면 유지보수가 훨씬 쉬워집니다.
// dio_client.dart
class DioClient {
final Dio _dio = Dio(
BaseOptions(
baseUrl: 'https://api.example.com',
connectTimeout: const Duration(seconds: 5),
receiveTimeout: const Duration(seconds: 5),
),
);
Future get(String path) async => await _dio.get(path);
Future post(String path, dynamic data) async => await _dio.post(path, data: data);
}
// user_api.dart
class UserApi {
final DioClient dioClient;
UserApi(this.dioClient);
Future<Response> getUserProfile() {
return dioClient.get('/user/profile');
}
}
// 사용 예시 (main.dart)
final api = UserApi(DioClient());
void loadUser() async {
final res = await api.getUserProfile();
print(res.data);
}
🛡️ 4. Interceptor로 토큰 자동 갱신
_dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
options.headers['Authorization'] = 'Bearer YOUR_TOKEN';
return handler.next(options);
},
onError: (DioException e, handler) {
if (e.response?.statusCode == 401) {
// 토큰 만료 시 재발급 로직
}
return handler.next(e);
},
),
);
→ 실무에서는 토큰 자동 갱신, 로깅, 로딩 상태 연동 등에 Interceptor가 필수입니다.
📌 정리
http
는 간단한 테스트에 적합Dio
는 실무에 꼭 필요한 확장 기능 제공- API 호출 코드는 기능별 클래스로 분리
- Interceptor를 통해 인증/에러/로딩 처리 통합
Flutter 앱이 커질수록 API 구조화와 안정적인 네트워크 통신은 필수입니다.
지금부터라도 Dio 기반 구조 설계를 연습해보세요!
반응형