반응형
안녕하세요!
오늘은 Flutter 프로젝트에서 공통 네트워크 통신 모듈을 구축하고,
이를 활용해서 명함 등록 API 연동까지 완료한 내용을 정리해보려고 합니다.
이번 작업을 통해 프로젝트의 통신 구조를 더 깔끔하고 일관성 있게 다듬을 수 있었어요. ✨
1. 공통 네트워크 통신 모듈 구축
네트워크 통신은 앱의 중요한 부분이기 때문에,
처음부터 공통 구조를 잘 잡아두는 게 정말 중요하다고 생각했습니다.
📌 구조
- DioClient: Dio 기본 설정 + 인터셉터 등록
- AuthInterceptor: 요청마다 자동으로 토큰 추가
- LoggerInterceptor: 요청/응답 내용을 콘솔에 로깅
- ApiConstants: API Base URL, 엔드포인트 관리
📂 파일 구성
lib/
├── core/
│ └── network/
│ ├── dio_client.dart
│ ├── api_constants.dart
│ └── interceptors/
│ ├── auth_interceptor.dart
│ └── logger_interceptor.dart
✅ 주요 포인트
- DioClient를 싱글턴 패턴으로 구성해서 앱 전체에서 하나의 인스턴스만 사용
- 모든 요청에 자동으로 토큰을 넣고, 로그도 깔끔하게 찍을 수 있도록 인터셉터 추가
- 타임아웃, 기본 헤더 등도 중앙에서 관리
2. 명함 등록 API 연동
명함 등록을 위한 API 엔드포인트는 다음과 같습니다.
- POST /전자명함앱/api/v1/cards/register
📝 보내야 할 데이터
필드설명
company | 회사명 |
department | 부서명 |
position | 직급 |
name | 이름 |
phoneNumber | 전화번호 |
이메일 |
사용자는 간단한 폼에 정보를 입력하고,
그 데이터를 서버에 전송하는 방식으로 명함을 등록할 수 있습니다.
3. 전체 통신 흐름 구성
통신 흐름은 Service → ViewModel → UI 구조로 만들었습니다.
3.1 Service (API 호출 담당)
class CardApiService {
final Dio _dio = DioClient().dio;
Future<void> registerCard({
required String company,
required String department,
required String position,
required String name,
required String phoneNumber,
required String email,
}) async {
await _dio.post(
'/cardtalk/api/v1/cards/register',
data: {
"company": company,
"department": department,
"position": position,
"name": name,
"phoneNumber": phoneNumber,
"email": email,
},
);
}
}
3.2 ViewModel (상태 관리)
class CardViewModel extends ChangeNotifier {
final CardApiService _cardApiService = CardApiService();
bool isLoading = false;
String? errorMessage;
Future<void> registerCard({
required String company,
required String department,
required String position,
required String name,
required String phoneNumber,
required String email,
}) async {
isLoading = true;
errorMessage = null;
notifyListeners();
try {
await _cardApiService.registerCard(
company: company,
department: department,
position: position,
name: name,
phoneNumber: phoneNumber,
email: email,
);
} catch (e) {
errorMessage = e.toString();
} finally {
isLoading = false;
notifyListeners();
}
}
}
3.3 UI (사용자 입력 + 요청 호출)
ElevatedButton(
onPressed: viewModel.isLoading
? null
: () {
context.read<CardViewModel>().registerCard(
company: _companyController.text,
department: _departmentController.text,
position: _positionController.text,
name: _nameController.text,
phoneNumber: _phoneController.text,
email: _emailController.text,
);
},
child: viewModel.isLoading
? const CircularProgressIndicator()
: const Text('명함 등록'),
)
4. 작업을 하며 느낀 점
- 통신 모듈을 공통으로 관리하니 새 API 추가할 때 훨씬 깔끔하고 빠르게 작업할 수 있었습니다.
- Service → ViewModel → UI 흐름을 확실히 구분해두니, 테스트나 유지보수도 편해질 것 같습니다.
- 다음에는 등록 완료 시 토스트 메시지나 화면 이동 처리까지 추가해서 UX를 조금 더 개선할 예정입니다.
✨ 마무리
이번 작업을 통해 플러터에서 네트워크 구조를 체계적으로 잡는 방법을 익혔고,
실제 API 연동까지 경험할 수 있어서 큰 도움이 되었습니다.
다음 글에서는, 명함 등록 후 성공 화면 이동 처리나
API 통신 실패 시 에러 핸들링에 대해 더 자세히 다뤄보겠습니다.
읽어주셔서 감사합니다! 🙌
반응형
'플러터 프로젝트' 카테고리의 다른 글
🗂️ [5화] 명함 리스트와 공유 기능은 이렇게 만들었습니다 (35) | 2025.06.18 |
---|---|
[4화] 플러터로 전자명함 앱 만들기 - 명함 등록 기능은 이렇게 만들었습니다! (26) | 2025.05.21 |
[2화] 플러터로 전자명함 앱 만들기 - 기능 명세 & 프로젝트 구조 소개 (12) | 2025.04.23 |
[1화] 자바 개발자가 처음 도전한 Flutter – 전자명함 앱을 만들기로 한 이유 (17) | 2025.04.21 |