📚

[Flutter] riverpod / retrofit / freezed でmicroCMS

2022/10/26に公開

microCMS、使ってみるととても簡単にAPIの作成、管理画面を作る事ができてとても良かったのでFlutterで使うことにしました。

まずはアカウント登録・スキーマの作成

https://document.microcms.io/manual/getting-started

こちらを参考にされてください。日本語なので本当にありがたい。

APIは自分で決める、でも何でも良いでしょう。

次にスキーマを作成します。

こちらもドキュメントを見るとスムーズ。

https://document.microcms.io/manual/create-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