📚
[Flutter] riverpod / retrofit / freezed でmicroCMS
microCMS、使ってみるととても簡単にAPIの作成、管理画面を作る事ができてとても良かったのでFlutterで使うことにしました。
まずはアカウント登録・スキーマの作成
こちらを参考にされてください。日本語なので本当にありがたい。
APIは自分で決める、でも何でも良いでしょう。
次にスキーマを作成します。
こちらもドキュメントを見るとスムーズ。
今回はこのような形のスキーマにしています。
URLやAPIキーなどは「APIプレビュー」を見ると全部書いてあります。わかりやすい。
次にFlutter側のプロジェクトの作成
プロジェクトの作成
flutter create --org com.yourdomain testapp
必要なライブラリをゲットする。
ctrl + shift +p
でdart addと打つと出てくるAdd Dependenciesを使うととてもやりやすいのでオススメです!
riverpodをはじめ必要なライブラリをインストールしていきます。このへんが必要。
pubspec.yaml
dependencies:
flutter:
sdk: flutter
hooks_riverpod: ^2.0.2
freezed_annotation: ^2.2.0
flutter_hooks: ^0.18.0
json_annotation: ^4.1.0
retrofit: ^3.3.1
dio: ^4.0.0
intl: ^0.17.0
cupertino_icons: ^1.0.2
flutter_dotenv: ^5.0.2
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^2.1.2
json_serializable: ^6.5.4
retrofit_generator: ^4.2.0
freezed: ^2.2.0
flutter_lints: ^2.0.1
APIをパースする。
freezed , retrofitを使ってレスポンスを作っていきます。
レスポンスの定義
freezedを使ってレスポンスを定義し、retrofitを使ってクライアントを作成していきます。
リストで作成しようとレスポンスはContents内に入って来ますので、適宜ラップしてあげます。
upsell_item_model.dart
import 'package:freezed_annotation/freezed_annotation.dart';
part 'upsell_item_model.freezed.dart';
part 'upsell_item_model.g.dart';
class UpSellItem with _$UpSellItem {
(explicitToJson: true)
factory UpSellItem(
{required String itemId,
required String itemName,
String? itemDescription,
UpSellItemImage? itemImage,
required int itemPrice}) = _UpSellItem;
factory UpSellItem.fromJson(Map<String, dynamic> json) =>
_$UpSellItemFromJson(json);
}
class UpSellItemResponse with _$UpSellItemResponse {
(explicitToJson: true)
factory UpSellItemResponse(
{required List<UpSellItem> contents,
required int totalCount,
required int offset,
required int limit}) = _UpSellItemResponse;
factory UpSellItemResponse.fromJson(Map<String, dynamic> json) =>
_$UpSellItemResponseFromJson(json);
}
class UpSellItemImage with _$UpSellItemImage {
factory UpSellItemImage(
{required String url,
required int height,
required int width}) = _UpSellItemImage;
factory UpSellItemImage.fromJson(Map<String, dynamic> json) =>
_$UpSellItemImageFromJson(json);
}
クライアントの定義
先程作ったモデルクラスを使用し、APIクライアントを定義します。
client.dart
(baseUrl: 'https://yourapp.microcms.io/api/v1/')
abstract class MicroCMSClient {
factory MicroCMSClient(Dio dio, {String baseUrl}) = _MicroCMSClient;
('/ipsell-items')
Future<UpSellItemResponse> getUpSellItems(
('X-MICROCMS-API-KEY') String apiKey);
}
コード生成
flutter pub run build_runner build --delete-conflicting-outputs
riverpodでClientを利用する
作ったクライアントをriverpodで使えるよう、Providerを定義していきます。
APIキーをハードコートしたくなかったので、flutter_dotenv
を使用しています。
upsell_items_provider
final dioProvider = Provider<Dio>((ref) => Dio());
final microCMSClientProvider = Provider<MicroCMSClient>((ref) {
final _dio = ref.watch(dioProvider);
return MicroCMSClient(_dio);
});
final upSellItemsProvider = FutureProvider<List<UpSellItem>>((ref) async {
final _dio = ref.watch(dioProvider);
final _client = ref.watch(microCMSClientProvider);
await dotenv.load(fileName: ".env");
final _response = await _client.getUpSellItems(dotenv.env['API_KEY']!);
return _response.contents;
});
Widgetで使う。
使いたい場所で作成したproviderを使っていきます。
Widget build(BuildContext context, WidgetRef ref) {
final upsellItems = ref.watch(upSellItemsProvider);
return ListView(
children: [
...upsellItems.when(
data: (items) => items
.map((upsellitem) => UpSellItemTileCard(upSellItem: upsellitem))
.toList(),
error: ((error, stackTrace) => [Text(error.toString())]),
loading: (() => [const Center(child: CircularProgressIndicator())]))
],
);
所感
初めてmicroCMS使ってみましたが、本当に使いやすくてびっくりしました。
Discussion