1. 개요
본 프로젝트는 장소 검색 앱입니다.
검색창에 검색어를 입력하면 5개의 장소를 표시합니다.
또한, 사용자의 현재 위치를 기반으로 행정 주소를 조회한 뒤, 해당 주소를 활용해 Naver Search API로 주변 장소를 검색합니다.
2. 프로젝트
1) GitHub
https://github.com/Meezzi/around_me_app
GitHub - Meezzi/around_me_app
Contribute to Meezzi/around_me_app development by creating an account on GitHub.
github.com
2) 기술 스택
- Flutter
- Riverpod: 상태 관리
- Geolocator: 위치 권한 및 현재 위치
- VWORLD API: 좌표 → 주소 변환
- Naver Search API: 장소 검색
- Dio: HTTP 요청
- Flutter Dotenv: 환경 변수(.env) 관리
- mocktail: 테스트 코드 작성
3) 구조
lib/
├── core/
│ ├── error/ # CustomException 정의
│ ├── geolocator/ # 현재 위치 불러오기
│ └── result/ # Result<T> 패턴
│
├── data/
│ ├── model/ # Place 모델
│ └── repository/ # LocationRepository 및 구현체
│
├── theme/ # 라이트, 다크 테마
│
├── ui/
│ └── pages/ # ViewModel, 위젯, Home Screen
│ └── home/
3. 트러블 슈팅
[Flutter] API 키 숨기기 (feat. dotenv)
1. 개요발급받은 API 키를 코드 안에서 직접 하드코딩한다면 키가 외부에 노출되어 악용될 가능성이 있고,팀 프로젝트를 진행한다면 일일이 자신의 키로 바꿔야 한다는 번거로움이 있을 것이다.
sfida.tistory.com
4. 회고
1) Result 패턴 도입
Flutter 앱은 ViewModel, Repository, Service 계층으로 구성된다.
이러한 구조 중 함수 실행이 실패하면 호출하는 곳에 오류를 전달해야 한다.
처음엔 try-catch를 통해 예외를 던져서 처리했다.
그래서 호출하는 곳에서도 try-catch를 사용해야 하는데 이는 비효율적인 것 같은 생각이 들었다.
예외처리에 대해 찾아본 결과 Result 패턴을 많이 사용한다는 것을 알게 되었다.
다행히 Flutter에서도 Result 패턴을 지원했기 때문에 효율적인 예외 처리를 위해 이 패턴을 도입했다.
이 패턴 덕분에 오류를 Result 객체로 처리하여 효율적으로 예외 처리를 할 수 있었다.
https://docs.flutter.dev/app-architecture/design-patterns/result
2) API 키 보안 처리
처음에는 키를 코드에 직접 작성했지만 dotenv 패키지를 추가하면서 키를 안전하게 관리하도록 개선했다.
API 키가 코드에 포함되면 GitHub에 노출될 위험이 있고,
협업 시 키 충돌이나 실수도 발생할 수 있기 때문에 보안성과 유지보수성을 위해서라도 dotenv 패키지를 사용하여 관리하는 것이 좋을 것 같다.
3) 테스트 코드 작성
API와 통신을 담당하는 Repository를 테스트하기 위해 mocktail 패키지를 사용했다.
외부 API 호출을 실제로 하지 않기 위해 Dio 객체를 mocking 하고, 테스트에 필요한 가짜 응답 데이터를 활용하여 테스트를 진행했다.
테스트를 진행할 때 mock 객체를 이용한다는 것만 알고 있었는데 이 프로젝트를 진행하면서 관련 사항에 대해 개념을 알고 나니 스스로가 성장한 기분이 들었다.
그래도 깔끔한 테스트 코드 작성을 위해 mocktail에 대해 더 공부해야할 것 같다.
4) DIP 원칙 준수
DIP는 의존성 역전 원칙으로 구현체에 의존하는게 아닌 추상화에 의존하는 것이다.
본 프로젝트에서는 LocationRepository를 추상화하고, LocationRepositoryImpl에서 실제 구현을 담당하도록 분리했다.
ViewModel에서는 추상화한 LocationRepository에 의존하도록 설계했다.
내 의도는 위와 같은데 이 부분이 코드로 잘 표현되었는지는 잘 모르겠다.
'Flutter' 카테고리의 다른 글
| [Flutter] Riverpod으로 상태관리하고, MVVM패턴 적용해서 Counter앱 만들기 (0) | 2025.05.02 |
|---|---|
| [Flutter] API 키 숨기기 (feat. dotenv) (0) | 2025.04.22 |
| [Flutter] MVVM 패턴, 앱 아키텍처 가이드 (0) | 2025.04.14 |
| [Flutter] Riverpod 상태 관리부터 개념 정리까지 (0) | 2025.04.11 |
| [Flutter] StatelessWidget, StatefulWidget, build() (0) | 2025.03.26 |