게시글 삭제
정말 삭제하시겠습니까?
2026 플러터 앱개발 끝까지 – 3강: Repository 적용, REST API CRUD, 이벤트 처리
[주요 목차]
REST API CRUD 완성하기
Repository로 네트워크 로직 분리
Riverpod 이벤트 처리와 스낵바
플러터로 앱을 만들다 보면 REST API CRUD를 여기저기 흩어 놓고 쓰게 되더라고요. 지난 강의에서 조회까지만 했는데, 이번에는 생성·수정·삭제까지 마무리하면서 Repository 패턴까지 적용해 보겠습니다. 실제 현업에서는 네트워크 통신 코드를 이렇게 분리해 두면 나중에 API가 바뀌어도 수정 범위가 확 줄어요. Riverpod의 ref를 활용해 Repository를 주입하는 방법과, 이벤트 대신 상태로 스낵바를 띄우는 실전 팁도 함께 담았습니다. 이 글을 끝까지 읽으면 2026 플러터 앱개발에서 Repository와 REST API CRUD, 이벤트 처리를 한 번에 정리할 수 있을 거예요.
2026 플러터 앱개발 끝까지 – 3강: Repository 적용, REST API CRUD, 이벤트 처리 · 실전 화면 1
REST API CRUD 완성하기
지난번에 GET으로 목록과 단일 조회만 했었는데, 이번에는 POST, PUT, DELETE까지 붙여봤습니다. 서버 스펙이 정해져 있으면 그냥 그에 맞춰 HTTP 메서드와 엔드포인트만 바꿔 주면 되더라고요. 예를 들어 새 노트를 추가할 때는 POST /notes에 JSON 바디로 content만 보내면 되고, 수정은 PUT /notes/{id}, 삭제는 DELETE /notes/{id}로 처리했습니다. 실제로 Postman으로 테스트해 보니 32번 노트를 PUT으로 content를 바꾸면 바로 목록에 반영되더라고요. 현업에서는 이런 식으로 서버 스펙 문서를 보고 정확히 맞추는 게 제일 중요합니다. Dio에서 post, put, delete를 호출할 때 headers에 Content-Type: application/json을 넣어주는 것도 잊지 마세요. 제가 실제로 해봤는데, 이 부분을 빼먹으면 415 에러가 나서 한참 헤맸습니다.
2026 플러터 앱개발 끝까지 – 3강: Repository 적용, REST API CRUD, 이벤트 처리 · 본문 이미지 2
Repository로 네트워크 로직 분리
기존 AsyncNotifier 안에 Dio 호출까지 다 들어가 있으면 나중에 API가 바뀔 때마다 Notifier를 다 고쳐야 하더라고요. 그래서 노트 관련 네트워크 요청만 모아 NoteRepository 클래스를 만들었습니다. fetchNotes, createNote, updateNote, deleteNote 메서드를 각각 Future로 빼고, baseUrl은 나중에 .env나 설정 파일로 숨길 수 있게 준비해 뒀습니다. Riverpod에서는 NoteRepositoryProvider를 StateProvider로 만들어 ref.read로 주입했는데, AsyncNotifier 안에서는 ref.read(NoteRepositoryProvider) 대신 build 메서드에서 ref.watch로 받아서 쓰는 게 더 깔끔하더라고요. 이렇게 분리하니 Notifier는 순수하게 상태만 관리하고, Repository는 오직 API 호출만 담당하게 되었습니다. 실제 프로젝트에서 이렇게 해두면 테스트할 때도 Repository를 Mock으로 쉽게 교체할 수 있어서 유지보수가 훨씬 수월했습니다.
2026 플러터 앱개발 끝까지 – 3강: Repository 적용, REST API CRUD, 이벤트 처리 · 현장 스냅 3
Riverpod 이벤트 처리와 스낵바
Riverpod에는 한 번만 보내는 이벤트가 없기 때문에 상태 기반으로 처리해야 합니다. NoteAction enum을 만들어 None, Added, Deleted 세 가지 상태를 정의하고, StateProvider로 NoteActionProvider를 만들었습니다. 추가나 삭제가 성공하면 Notifier에서 state = NoteAction.added로 바꿔주고, ConsumerStatefulWidget의 initState에서 ref.listenManual로 구독합니다. 스낵바 메시지는 switch로 Added면 “노트가 추가되었습니다”, Deleted면 “노트가 삭제되었습니다”로 분기해서 ScaffoldMessenger.of(context).showSnackBar로 띄웠습니다. 구독은 dispose에서 subscription.close()로 꼭 해제해야 메모리 누수가 안 생기더라고요. 이렇게 상태로 이벤트를 흉내 내는 방식이 처음엔 좀 번거롭지만, 실제 앱에서는 토스트·다이얼로그·페이지 이동까지 깔끔하게 처리할 수 있어서 지금은 이 패턴을 주로 쓰고 있습니다.
[자주 묻는 질문]
Flutter Riverpod에서 Repository 패턴을 적용하면 어떤 장점이 있나요?
네트워크 통신 코드를 Notifier에서 완전히 분리할 수 있어서 API 변경 시 수정 범위가 줄어듭니다. 테스트할 때도 Repository만 Mock으로 교체하면 되고, Notifier는 순수 상태 관리에만 집중할 수 있어 코드가 훨씬 깔끔해집니다. 실제로 제가 진행한 프로젝트에서도 이 구조로 바꾼 뒤 유지보수 시간이 절반 가까이 줄었어요.
Riverpod에서 이벤트 대신 상태로 스낵바를 띄우는 이유는 무엇인가요?
Riverpod 자체에 일회성 이벤트 전송 기능이 없기 때문입니다. 상태를 변경하고 listenManual로 구독하는 방식이 가장 안정적이며, dispose에서 구독을 해제하면 메모리 이슈도 방지할 수 있습니다. 현업에서는 이 패턴을 자주 사용합니다.
Dio로 REST API 호출할 때 주의할 점이 있나요?
Content-Type 헤더를 application/json으로 꼭 넣어야 하고, 서버가 요구하는 HTTP 메서드와 엔드포인트를 정확히 맞춰야 합니다. 특히 삭제 시 404가 발생하면 try-catch로 처리하는 습관을 들이면 에러 대응이 훨씬 수월해집니다.