Repository라는 이름을 붙이는 이유는 데이터 접근 계층을 나타내기 위해서입니다.
주요 목적은?
Repository는 API, 데이터베이스, 로컬 파일, 캐시(데이터 소스) 등에서 데이터를 동일한 인터페이스를 통해 접근할 수 있도록 해줍니다. 즉, 특정 데이터 소스에 종속되지 않고 일관된 방식으로 데이터를 사용할 수 있게 설계할 수 있습니다.
의존성 역전 원칙(Dependency Inversion Principle)을 실현 - DIP
상위 레벨의 비즈니스 로직(서비스 계층)이 하위 레벨의 데이터 접근 세부사항(API, 데이터베이스 등)에 직접적으로 의존하지 않고 Repository 인터페이스에 의존하게 됩니다.
단일 책임 원칙(SRP)
Repository는 데이터를 가져오거나 저장하는 하나의 책임만 가집니다. 명확한 역할과 책임을 가짐.
repository/post_repository_impl.dart
import 'dart:convert';
import 'package:class_mvvm/models/post.dart';
import 'package:class_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(), // Json으로 변환
);
if(response.statusCode == 201 || response.statusCode == 200){
return Post.fromJson(response.data); // 응답 코드가 200, 201 --> 변환
}else{
throw Exception('게시글 생성 실패');
}
}catch(e){
throw Exception('게시글 생성 중 오류 발생 : $e');
}
}
// 게시글 삭제
@override
// 삭제할 게시글의 고유 ID
Future<void> deletePost(int id) async{
try{
final response = await _dio.delete('/posts/${id}');
// 응답 코드가 200이 아니면 예외 발생
if(response.statusCode != 200){
throw Exception('게시글 삭제 실패');
}
}catch(e){
throw Exception('게시글 삭제 중 오류 발생 : $e');
}
}
// 특정 게시글 조회
@override
// 조회할 게시글의 고유 ID
Future<Post> fetchPostById(int id) async{
try{
final response = await _dio.get('/posts/$id');
// 응답코드가 200이면 --> 변환 // 아니면 예외 발생
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;
return data.map((json) => Post.fromJson(json)).toList(); // JSON 데이터를 Post 객체로 반환 --> 이걸 List로 반환
}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');
}
}
}
async: 함수가 비동기로 동작하며 Future를 반환함을 명시.
await: 비동기 작업이 완료될 때까지 기다림.
'Flutter > MVVM 활용' 카테고리의 다른 글
[Flutter] (MVVM 활용) 화면의 데이터(상태)를 관리하는 PostListViewModel 을 먼저 만들어 보자. - 6 (0) | 2024.11.19 |
---|---|
[Flutter] (MVVM 활용) PostRespository를 중앙에서(컨테이너) 관리하는 Provider 계열을 만들어 보자. - 5 (0) | 2024.11.19 |
[Flutter] (MVVM 활용) API에서 사용할 데이터 구조를 정의하기 위해 Post 클래스를 만들어 봅시다.(모델링 작업) - 3 (0) | 2024.11.19 |
[Flutter] (MVVM 활용) Http 통신 클라이언트 Dio 객체를 만들어 보자 - 2 (0) | 2024.11.19 |
[Flutter] (MVVM 활용) 플러터 프로젝트 생성 - 1 (0) | 2024.11.19 |