riverpod를 이용해서 API통신을 곁들인 MVVM 예제를 작성해보겠습니다.
코드가 길어질 것 같아 MVVM에 대한 개념은 생략하겠습니다.
매우 간단하게 설명하면 UI 그리는 View파일, 비즈니스 로직들어가는 ViewModel, 데이터 파싱하는 Model 파일 3개로 나눠서 코딩해주시면 됩니다.
flutter pub add flutter_riverpod
dart pub add riverpod_generator
flutter pub add riverpod_annotation
dart pub add dio
flutter pub add freezed_annotation
flutter pub add dev:build_runner
flutter pub add dev:freezed
flutter pub add json_annotation
flutter pub add dev:json_serializable
riverpod와 API 통신을 위해 dio 패키지를 추가합니다.
추가로 쉽게 코딩하기 위해 riverpod 생성 패키지와 json 파싱 생성기도 추가합니다.
코드 생성기는 익숙하지 않으면 복잡하실 수도 있지만 생각보다 간단하므로 한번 써보시는걸 추천합니다.
JSON to Dart
JSON to Dart Paste your JSON in the textarea below, click convert and get your Dart classes for free. Handcrafted by Javier Lecuona Github json_to_dart Code Twitter
javiercbk.github.io
파싱의 경우에는 그냥 데이터만 해당 사이트에 넣어서 자동 생성하셔도 무방합니다.
JSONPlaceholder - Free Fake REST API
{JSON} Placeholder Free fake and reliable API for testing and prototyping. Powered by JSON Server + LowDB. Serving ~3 billion requests each month.
jsonplaceholder.typicode.com
API 통신을 위한 데이터는 해당 예제 사이트를 활용하겠습니다.
https://jsonplaceholder.typicode.com/posts/1
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
해당 요청을 통해 얻는 데이터입니다. 해당 데이터를 파싱 할 수 있도록 Flutter 프로젝트 생성 후 코드를 작성해보겠습니다.
import 'package:freezed_annotation/freezed_annotation.dart';
part "model.freezed.dart";
part 'model.g.dart';
@freezed
class Model with _$Model {
factory Model(
{required int userId,
required int id,
required String title,
required String body}) = _Model;
factory Model.fromJson(Map<String, dynamic> json) => _$ModelFromJson(json);
}
다음과 같이 Model 코드를 작성합니다. 3, 5번줄은 코드 생성기를 위한 추가 문법입니다.
이후 코드 생성을 위해 dart run build_runner build 를 터미널에 실행합니다.
명령어가 성공적으로 실행되면 추가 코드 작성 필요 없이 자동으로 코드가 생성됩니다.
이렇게 되면 Model 부분의 코드는 성공적으로 작성하였습니다.
import 'package:blog_posting/riverpod_mvvm_api/model.dart';
import 'package:dio/dio.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'view_model.g.dart';
@riverpod
class ViewModel extends _$ViewModel {
final dio = Dio();
@override
AsyncValue<Model> build() {
getData();
return const AsyncValue.loading();
}
Future<void> getData() async {
final response =
await dio.get('https://jsonplaceholder.typicode.com/posts/1');
state = AsyncValue.data(Model.fromJson(response.data));
}
}
다음과 같이 데이터를 가져오는 ViewModel 파일을 작성해줍니다. (반드시 part 'view_model.g.dart'; 도 적어줘야 코드가 자동 생성됩니다)
이후 flutter pub run build_runner build 를 실행하면
다음과 같이 View_model.g 파일이 생성됩니다.
이제 View 파일을 간단히 작성해보겠습니다.
View 파일은 데이터의 상태에 따라 완료, 로딩, 에러 3개의 상태로 나누어 작성해보겠습니다.
import 'package:blog_posting/riverpod_mvvm_api/view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class View1 extends ConsumerWidget {
const View1({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final viewWatch = ref.watch(viewModelProvider);
final viewRead = ref.read(viewModelProvider.notifier);
return Scaffold(
appBar: AppBar(
title: const Text('riverpod!'),
centerTitle: true,
),
body: Column(
children: [
viewWatch.when(
data: (data) => Text(data.toJson().toString()),
error: (error, stackTrace) => Text('에러: $error'),
loading: () => const Center(child: CircularProgressIndicator()),
),
],
),
);
}
}
View라고 작성 시 기존 위젯과 충돌이 발생하여 View1로 작성하였습니다.
riverpod의 상태를 추적 할 수 있도록 watch와 read를 변수를 추가합니다.
Watch.when 을 이용하여 상태에 따른 화면을 구현합니다.
저는 간단하게 확인만 하기위해 완료시에는 데이터를 출력, 에리 발생 시에는 에러내용, 로딩중에는 로딩창이 표시되도록 하였습니다.
이제 전체적인 코드를 실행하면 다음과 같이 로딩화면 후 데이터가 표시되는 것을 확인 할 수 있습니다.
전체 코드는 Github을 참고해주세요.
Flutter_Blog/lib/riverpod_mvvm_api at master · beomsuong/Flutter_Blog
Contribute to beomsuong/Flutter_Blog development by creating an account on GitHub.
github.com
잘못된 내용 지적이나 질문 댓글 환영합니다~
'Flutter' 카테고리의 다른 글
Flutter) env파일을 암호화가 될까? (0) | 2024.06.25 |
---|---|
Flutter) 비동기 요청을 병렬로 처리하기 (0) | 2024.06.25 |
Go_router에 URL 전달하기 (0) | 2024.06.05 |
Flutter) Riverpod 사용 정리 (0) | 2024.05.28 |
riverpod http 요청 예시 (0) | 2024.05.27 |