| 주요 목적은? Repository는 API, 데이터베이스, 로컬 파일, 캐시(데이터 소스) 등에서 데이터를 동일한 인터페이스를 통해 접근할 수 있도록 해줍니다. 즉, 특정 데이터 소스에 종속되지 않고 일관된 방식으로 데이터를 사용할 수 있게 설계할 수 있습니다. 의존성 역전 원칙(Dependency Inversion Principle)을 실현 - DIP 상위 레벨의 비즈니스 로직(서비스 계층)이 하위 레벨의 데이터 접근 세부사항(API, 데이터베이스 등)에 직접적으로 의존하지 않고 Repository 인터페이스에 의존하게 됩니다. 단일 책임 원칙(SRP) Repository는 데이터를 가져오거나 저장하는 하나의 책임만 가집니다. 명확한 역할과 책임을 가짐. |
repository/post_repository.dart
import '../models/post.dart';
abstract class PostRepository {
// 모든 게시글 목록을 가져온다.
Future<List<Post>> fetchPosts();
// 새로운 게시글을 생성한다.
Future<Post> createPost(Post post);
// 기본 게시글을 수정한다.
Future<Post> updatePost(Post post);
// 특정 게시글을 삭제한다. 게시글 PK
Future<void> deletePost(int id);
// 특정 게시글 하나를 요청한다. 게시글 PK
Future<Post> fetchPostById(int id);
// ...
}
repository/post_repository_impl.dart
import 'package:class_riverpod_mvvm/models/post.dart';
import 'package:class_riverpod_mvvm/repository/post_repository.dart';
import 'package:dio/dio.dart';
class PostRepositoryImpl implements PostRepository {
final Dio _dio;
// dio 을 가져올 때 우리가 사용할 수 있는 방법은
// 1. 생상자 주입을 통한 - 의존성을 수동으로 관리
// 2. 리버팟을 활용한 관리 - x
PostRepositoryImpl(this._dio);
@override
Future<Post> createPost(Post post) async {
// 통신 관련 코드는 무조건 예외 처리 코드 습관화
try {
final response = await _dio.post(
'/posts',
data: post.toJson(),
);
if (response.statusCode == 201 || response.statusCode == 200) {
return Post.fromJson(response.data);
} else {
throw Exception('게시글 생성 실패');
}
} catch (e) {
throw Exception('게시글 생성 중 오류 발생 : $e');
}
}
@override
Future<void> deletePost(int id) async {
try {
final response = await _dio.delete('/posts/${id}');
if (response.statusCode != 200) {
throw Exception('게시글 삭제 실패');
}
} catch (e) {
throw Exception('게시글 삭제 중 오류 발생 : $e');
}
}
@override
Future<Post> fetchPostById(int id) async {
try {
final response = await _dio.get('/posts/$id');
if(response.statusCode == 200) {
return Post.fromJson(response.data);
} else {
throw Exception('게시글 불러 오기 실패');
}
} catch(e) {
throw Exception('게시글 불러 오는 중 오류 발생 : $e');
}
}
@override
Future<List<Post>> fetchPosts() async {
try {
final response = await _dio.get('/posts');
if(response.statusCode == 200) {
// [ '{userId : 홍길동, id: 1 ...}' , '' , '' , '' ]
List<dynamic> data = response.data;
// [ 'Post(,,,)' , 'Post(,,,)' , 'Post(,,,)' , 'Post(,,,)' ]
return data.map((json) => Post.fromJson(json)).toList();
} else {
throw Exception('게시글 불러 오기 실패');
}
} catch(e) {
throw Exception('게시글 불러 오는 중 오류 발생 : $e');
}
}
@override
Future<Post> updatePost(Post post) async {
try {
final response = await _dio.put(
'/posts/${post.id}',
data: post.toJson(),
);
if (response.statusCode == 201 || response.statusCode == 200) {
return Post.fromJson(response.data);
} else {
throw Exception('게시글 수정 실패');
}
} catch (e) {
throw Exception('게시글 수정 중 오류 발생 : $e');
}
}
}
'Flutter > revierpod과 MVVM 활용' 카테고리의 다른 글
| 화면의 데이터(상태)를 관리하는 PostListViewModel 을 먼저 만들어 보자. - 6 (0) | 2024.12.18 |
|---|---|
| PostRespository를 중앙에서(컨테이너) 관리하는 Provider 계열을 만들어 보자. - 5 (0) | 2024.12.18 |
| API에서 사용할 데이터 구조를 정의하기 위해 Post 클래스를 만들어 봅시다.(모델링 작업) - 3 (0) | 2024.12.17 |
| Http 통신 클라이언트 Dio 객체를 만들어 보자. - 2 (0) | 2024.12.17 |
| 플러터 프로젝트 생성 - 1 (0) | 2024.12.17 |