5.7 KiB
5.7 KiB
네트워크 모듈 사용 가이드
개요
이 네트워크 모듈은 네이버 단축 URL 처리와 로컬 API 검색을 위한 통합 솔루션을 제공합니다. Dio 기반으로 구축되어 재시도, 캐싱, 로깅 등의 기능을 제공합니다.
주요 기능
- 네이버 단축 URL 리다이렉션 처리
- HTML 스크래핑으로 식당 정보 추출
- 네이버 로컬 검색 API 통합
- 자동 재시도 및 에러 처리
- 응답 캐싱으로 성능 최적화
- 네트워크 불안정 상황 대응
사용 방법
1. 네이버 지도 URL에서 식당 정보 추출
import 'package:lunchpick/data/datasources/remote/naver_search_service.dart';
final searchService = NaverSearchService();
try {
// 일반 네이버 지도 URL
final restaurant = await searchService.getRestaurantFromUrl(
'https://map.naver.com/p/restaurant/1234567890',
);
// 단축 URL도 자동 처리
final restaurant2 = await searchService.getRestaurantFromUrl(
'https://naver.me/abc123',
);
print('식당명: ${restaurant.name}');
print('카테고리: ${restaurant.category}');
print('주소: ${restaurant.roadAddress}');
} catch (e) {
print('오류 발생: $e');
}
2. 키워드로 주변 식당 검색
// 현재 위치 기반 검색
final restaurants = await searchService.searchNearbyRestaurants(
query: '파스타',
latitude: 37.5666805,
longitude: 126.9784147,
maxResults: 20,
sort: 'random', // 정확도순 정렬 (기본값)
);
for (final restaurant in restaurants) {
print('${restaurant.name} - ${restaurant.roadAddress}');
}
3. 식당 상세 정보 검색
// 식당 이름과 주소로 상세 정보 검색
final details = await searchService.searchRestaurantDetails(
name: '맛있는 한식당',
address: '서울 중구 세종대로',
latitude: 37.5666805,
longitude: 126.9784147,
);
if (details != null) {
print('영업시간: ${details.businessHours}');
print('전화번호: ${details.phoneNumber}');
}
4. 네트워크 에러 처리
import 'package:lunchpick/core/errors/network_exceptions.dart';
try {
final restaurant = await searchService.getRestaurantFromUrl(url);
} on ConnectionTimeoutException {
// 연결 타임아웃
showSnackBar('네트워크 연결이 느립니다. 다시 시도해주세요.');
} on NoInternetException {
// 인터넷 연결 없음
showSnackBar('인터넷 연결을 확인해주세요.');
} on ApiKeyException {
// API 키 설정 필요
showSnackBar('네이버 API 키를 설정해주세요.');
} on NaverMapParseException catch (e) {
// 파싱 오류
showSnackBar('식당 정보를 가져올 수 없습니다: ${e.message}');
} catch (e) {
// 기타 오류
showSnackBar('알 수 없는 오류가 발생했습니다.');
}
설정
API 키 설정
네이버 로컬 검색 API를 사용하려면 API 키가 필요합니다:
- 네이버 개발자 센터에서 애플리케이션 등록
- Client ID와 Client Secret 발급
- 값을 base64로 인코딩한 뒤
flutter run --dart-define으로 전달:
NAVER_CLIENT_ID=$(printf 'YOUR_CLIENT_ID' | base64)
NAVER_CLIENT_SECRET=$(printf 'YOUR_CLIENT_SECRET' | base64)
flutter run \
--dart-define=NAVER_CLIENT_ID=$NAVER_CLIENT_ID \
--dart-define=NAVER_CLIENT_SECRET=$NAVER_CLIENT_SECRET
로컬에서 빠르게 확인할 때는 base64 인코딩을 생략할 수 있습니다.
네트워크 설정 커스터마이징
lib/core/network/network_config.dart에서 타임아웃, 재시도 횟수 등을 조정할 수 있습니다:
class NetworkConfig {
static const int connectTimeout = 15000; // 15초
static const int maxRetries = 3; // 최대 3회 재시도
static const Duration cacheMaxAge = Duration(minutes: 15); // 15분 캐싱
}
아키텍처
lib/
├── core/
│ ├── errors/
│ │ ├── app_exceptions.dart # 앱 전체 예외 클래스들
│ │ ├── data_exceptions.dart # 데이터 레이어 예외
│ │ └── network_exceptions.dart # 네트워크 예외
│ └── network/
│ ├── network_client.dart # Dio 기반 HTTP 클라이언트
│ ├── network_config.dart # 네트워크 설정
│ └── interceptors/
│ ├── retry_interceptor.dart # 재시도 로직
│ └── logging_interceptor.dart # 로깅
├── data/
│ ├── api/
│ │ └── naver_api_client.dart # 네이버 API 클라이언트
│ └── datasources/
│ └── remote/
│ ├── naver_map_parser.dart # HTML 파싱
│ └── naver_search_service.dart # 통합 검색 서비스
주의사항
- API 키 보안: API 키는 절대 Git에 커밋하지 마세요.
.gitignore에 추가하세요. - 요청 제한: 네이버 API는 일일 요청 제한이 있습니다. 과도한 요청을 피하세요.
- 캐싱: 동일한 요청은 15분간 캐싱됩니다. 실시간 정보가 필요한 경우
useCache: false옵션을 사용하세요. - 웹 환경: 웹에서는 CORS 제한으로 인해 프록시 서버를 통해 요청합니다.
문제 해결
CORS 에러 (웹)
웹 환경에서 CORS 에러가 발생하면 프록시 서버가 일시적으로 사용 불가능한 상태일 수 있습니다. 잠시 후 다시 시도하거나 직접 입력 기능을 사용하세요.
타임아웃 에러
네트워크가 느린 환경에서는 NetworkConfig의 타임아웃 값을 늘려보세요.
API 키 에러
API 키가 올바르게 설정되었는지 확인하고, 네이버 개발자 센터에서 API 사용 권한이 활성화되어 있는지 확인하세요.