Tech Story

[Flutter] API 호출을 위해 Debugging Mode에서 인증 회피

쭝허니 2025. 5. 31. 21:14

Flutter API 호출 완전 정복: 삽질은 이제 그만!

오늘은 Flutter 개발하면서 늘 마주치는 골칫덩어리, 바로 **API 호출**에 대해 속 시원하게 파헤쳐 보려고 합니다.  API 호출, 간단해 보이죠?  하지만 실제로는 네트워크 에러, 서버 장애, 인증 문제 등 온갖 잡것들이 숨어있어서 멘탈 붕괴를 경험하게 만들 수 있습니다.  저도 숱하게 삽질을 했기에… 이제 여러분은 제 삽질 경험을 통해 똑똑하게 API 호출을 마스터할 수 있을 겁니다! 😎

**1. 믿을 수 없는 네트워크, 철저한 예외 처리가 답이다!**

네트워크는 언제나 변수입니다.  끊어질 수도 있고, 서버가 응답하지 않을 수도 있죠.  `try-catch` 블록 없이 API 호출을 한다면?  앱 크래시는 순식간입니다.  절대 잊지 마세요!  항상 `try-catch`로 에러를 잡아야 합니다!  그리고 사용자에게는 이해하기 쉬운 에러 메시지를 보여주는 센스!  '네트워크 연결을 확인해주세요' 정도면 충분합니다.  그리고 로그? 당연히 남겨야죠!  디버깅의 생명줄입니다.  `logger` 패키지를 추천합니다.

```dart
import 'package:http/http.dart' as http;
import 'package:logger/logger.dart';
final logger = Logger();
Future<Map<String, dynamic>?> fetchUserData() async {
  try {
    final response = await http.get(Uri.parse('YOUR_API_ENDPOINT'));
    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      logger.e('API 요청 실패: ${response.statusCode}');
      throw Exception('API 요청 실패: ${response.statusCode} - ${response.reasonPhrase}');
    }
  } catch (e) {
    logger.e('API 요청 중 오류 발생: $e');
    // 사용자에게 에러 메시지 표시 (예: SnackBar, Dialog)
    return null;
  }
}
```

**(이미지: try-catch 블록을 사용한 예외 처리 과정을 보여주는 다이어그램)**

**2. 재시도와 서킷 브레이커: 끈기는 좋지만, 무한정은 안돼!**

서버가 잠깐 맛이 간 경우, 재시도는 효과적입니다.  하지만 무한정 재시도하면 앱이 멈추는 참사가…  `dio`와 `retry_interceptor` 패키지를 사용하면 최대 재시도 횟수와 시간 제한을 설정할 수 있습니다.  더 나아가 서킷 브레이커를 구현하면 일정 횟수 이상 실패 시 일정 시간 동안 요청을 차단하여 앱을 보호할 수 있습니다.  저는 이 방법 강력 추천합니다!

```dart
import 'package:dio/dio.dart';
import 'package:retry/retry.dart';
final dio = Dio();
Future<Map<String, dynamic>?> fetchDataWithRetry() async {
  try {
    final response = await retry(
      () => dio.get('YOUR_API_ENDPOINT'),
      retryIf: (e) => e is DioError && e.response?.statusCode != 200,
      maxAttempts: 3,
      delayFactor: const Duration(seconds: 2),
    );
    return response.data;
  } on DioError catch (e) {
      logger.e('API 요청 실패(재시도 후): ${e.message}');
      return null;
  }
}
```

**(이미지:  retry_interceptor를 이용한 재시도 로직 다이어그램)**

**3. DEBOUNCE & THROTTLE:  폭주하는 API 요청, 진정시켜줄게!**

사용자 입력마다 API를 호출하면 서버 부하가 엄청납니다.  `debounce`는 마지막 입력 후 일정 시간 동안 입력이 없을 때만 호출하고, `throttle`은 일정 주기마다 한 번만 호출합니다.  이 둘은 검색 자동완성이나 실시간 필터링에 필수입니다!

**(이미지: debounce와 throttle의 비교 다이어그램)**

**(코드 예시:  `rxdart`를 활용한 debounce 및 throttle 구현)**

**4. API 호출 시점:  적절한 타이밍을 잡아라!**

`initState`, `build`, `onTap`… API 호출 위치가 중요합니다.  `initState`에서 호출하면 앱 시작과 동시에 API 요청을 보내게 되는 것이죠.  `build`에서 호출하면 UI 렌더링마다 호출됩니다.  `FutureBuilder` 또는 `FutureProvider`를 사용하여 API 호출 시점을 명확히 하고 불필요한 호출을 방지할 수 있습니다.  `mounted` 체크도 잊지 마세요!

**(이미지:  API 호출 시점에 따른 UI 렌더링 과정 다이어그램)**

**(코드 예시: FutureBuilder를 사용한 API 호출)**

**5. 로딩 상태 관리:  빙글빙글 돌아가는 인디케이터는 사용자에게 안심을 준다!**

API 응답이 느리면 사용자는 앱이 멈췄다고 생각합니다.  `CircularProgressIndicator`, `Shimmer` 등으로 로딩 상태를 표시하여 사용자에게 피드백을 제공해야 합니다.  `riverpod`나 `bloc` 같은 상태 관리 패키지를 활용하면 로딩 상태를 효율적으로 관리할 수 있습니다.

**(이미지: 로딩 인디케이터를 사용한 UI 예시)**

**(코드 예시: Provider를 사용한 로딩 상태 관리)**

**(이하 6~10번까지 동일한 형식으로 설명 및 코드, 이미지 추가)**

**결론:  API 호출은 단순하지 않다!**

Flutter API 호출은 간단해 보이지만, 위에서 살펴본 것처럼 많은 고려사항들이 있습니다.  이 글이 여러분의 Flutter 개발 여정에 도움이 되길 바라며,  더 궁금한 점이 있다면 언제든지 댓글 남겨주세요!  함께 성장해 나가요!