👁️

Riverpodは使うべきなのか?

2025/02/13に公開

📦個人が作ったパッケージという悩み

FlutterエンジニアだとRiverpod使いますよね。私も使います。今やってるIOTのお仕事では使っておりませんが😅
あれはremiさんが作った個人のパッケージだからもしメンテナンスされなくなったら困るリスクがある。

SwiftUIで人気のTCAも公式のものではないので同じようなもの。

https://riverpod.dev/ja/

使うべきか使わないべきか

もし使わないと他の企業の面談で。。。

🧑‍💼「珍しいですね」
🐈「メンテナンスを考えるとパッケージの使用は最小限にしたく(^_^;)」
🐈「使いまくった方がいいですか?」
🧑‍💼「小さいアプリなので既存のコードが活かせるなら笑。規模が大きいとどうなのでしょうか?」
🐈「あー俺ちゃんは使いすぎないほうがいいと思ってるもんね」

こんなこと聞かれる。もし長く続いているプロダクトなら入れない方がいいのかもしれない。自社開発だとこの辺の悩みが出てくる。

🚨課題

  1. バージョンアップした
  2. またした
  3. generatorが出てきた
  4. なんかまた出た
  5. メンテナンスされなくなった
  6. 😱

気に入ってるライブラリがメンテナンスされなくなることは他の言語でもあります。Next.jsだって、Pages Routerのままの企業がありますし😅

プロダクトを持っている企業はビジネスを成功させるのが目的なので技術選定は慎重にする。

まさか、StatefulWidgetなのか?
使ってますが、setState()はあまりない。記憶が正しければ7箇所にしかない?

どうやって状態管理してるの?
リアクティブプログラミングです。何それ?
Streamで状態管理してる。昔でいうところのBlocかな。これは今は違うようですが。

納品して終わりの開発だと流行りの技術がいいからと、Riverpodやgo_router_builderを使いたがる傾向があります。でも使わなくても目的は達成できるようだ。

デザインパターンやDart3.0も取り入れつつレガシーなわけではなくメンテナンスを意識したアプリを作っている。


副業でもあったのですが、Webシステムを大学生に作らせると、流行りのAuth.jsとかPrismaとか他のもその他多数入れたがバグだらけのものを作った。。。

Supabase公式もこれうちは推奨してないことを言ってるようだ。。。
https://authjs.dev/getting-started/adapters/supabase?framework=next-js

This adapter is developed by the community and not officially maintained or supported by Supabase. It uses the Supabase Database to store user and session data in a separate next_auth schema. It is a standalone Auth server that does not interface with Supabase Auth and therefore provides a different feature set.

If you’re looking for an officially maintained Auth server with additional features like built-in email server, phone auth, and Multi Factor Authentication (MFA / 2FA), please use Supabase Auth with the Auth Helpers for Next.js.

このアダプタはコミュニティによって開発されており、Supabase による公式な保守やサポートは行っていません。Supabase データベースを使用して、ユーザとセッションのデータを別の next_auth スキーマに格納します。このアダプタはSupabase Authとインタフェースを持たないスタンドアロンのAuthサーバです。

組み込みのメールサーバ、電話認証、多要素認証 (MFA / 2FA) などの追加機能を備えた、公式に保守されている認証サーバをお探しの場合は、Supabase Auth と Next.js 用の認証ヘルパーをご利用ください。

🤔なぜこんなことが起きたのでしょう
😅対話しないからです。なぜ議論しないか???

納品して契約終わりの受託やSESだと流行りのものを入れたがるところもありました。ref.listenが4個あったような😇

使っていいのか。。。。

プログラミングができる人はパッケージに頼らないと聞いた。すごいなーと思った。これができればパッケージ多用する現場に行っても通用するとか???

とはいえ

昔、StatefulWidgetだけでアプリを作ると嫌がれたことがありました。私も好きではないです。Reactのコードも書ける私は、hooks_riverpodとflutter_hooksを好んでよく使います。案件の面談受けるたびにこればかり使う企業が目立つ。元々Webのエンジニアの人が多いから、似てるなーと好むのでしょう。

https://riverpod.dev/ja/docs/concepts/about_hooks

営業さんからもRiverpodとスキルシートに書かれていないせいで弾かれる人がいるそうです😅
年数あればいけるのでは???

好みなのだろうけど、プロダクトを持っている企業は責任を持たなければいけないので技術選定は慎重にやる傾向があります。

受託やSESだと新しいものを好むところもあればテンプレートを使い回しのところもある。まあこっちの方が新しい印象ありました。普段はこっちなのでモダンなのとレガシーなものを経験した。

責任を持つ

iOSDCに行ったときに、SwiftUIだとTCAを使うと聞いたのですが、使わないという人がいました。理由は剥がすのが大変だからだそうです😅

なるほど。メンテナンスを意識している。今の案件でも同じこと言われRiverpodは使いすぎないようにするコードを意識するようにしました。以前のわたしのコードだと仕事で使われていたので、こんな感じで書いてましたね。全部に。。。

ずっとやってるのでこれに抵抗がない。でももしプロバイダーここはいらないとかバージョンアップして、書き方変わったりもっと便利なのが出てきたら移行作業が必要だ。

class UserApi {
  (this.ref);
  Ref ref;
}

以前実験で書いてたコードを参考にしたので動かないかもですが、dioのインスタンスを渡したり、リポジトリクラスをインスタンス化して、FutureProviderやAsyncNotifierに渡すプロバイダーだけ作ってクラスに、Refを使いすぎるのを避けました。

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:riverpod/riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_new/domain/user.dart';

part 'dio.g.dart';


Dio dio(Ref ref) {
  return Dio(
    BaseOptions(
      baseUrl: 'https://xxxxxxxxxxxxxx',
      headers: {
        HttpHeaders.contentTypeHeader: 'application/json',
      },
    ),
  );
}

// UserApi class to handle HTTP requests
class UserApi {
  final Dio _dio;

  UserApi(this._dio);

  Future<Response> getUser(int id) {
    return _dio.get('/users/$id');
  }

  Future<Response> createUser(String email, String password) {
    return _dio.post(
      '/users',
      data: {
        'email': email,
        'password': password,
      },
    );
  }
}

// Provider for UserApi

UserApi userApi(Ref ref) {
  final dio = ref.watch(dioProvider);
  return UserApi(dio);
}

// Provider for UserApiRepository

UserApiRepository userApiRepository(Ref ref) {
  final userApi = ref.watch(userApiProvider);
  return UserApiRepositoryImpl(userApi);
}

// Repository interface
abstract interface class UserApiRepository {
  Future<User> getUser(int id);
  Future<void> createUser(String email, String password);
}

// Repository implementation
class UserApiRepositoryImpl implements UserApiRepository {
  final UserApi _userApi;

  UserApiRepositoryImpl(this._userApi);

  
  Future<User> getUser(int id) async {
    final response = await _userApi.getUser(id);
    return User.fromJson(response.data);
  }

  
  Future<void> createUser(String email, String password) async {
    await _userApi.createUser(email, password);
  }
}

昔はねclass {}の中に、Ref refばかり書いておりました。悪いことではないと思うが保守して長く使うアプリだと、できるだけライブラリ依存を減らしいたいそうで配慮が必要だなと思いました。

最後に

好きに作って良いと言われたらプロバイダーを使いまくるコードを見たことがあります。Firebase/Supabaseしか使っていないならこれでいいでしょうけど、API通信をするプロジェクトに入ると、クラスの継承やデザインパターンを使用したコードがありオブジェクト思考で頑張ることができるのを知った。

とはいえ、Reactのpropsのようにコンポーネントの引数に値を渡すバケツリレーと同じように、コンストラクタ引数に値を渡すのを複数のファイルでやるのを好まない人もいます。わたしもNotifier + freezedでやるのが好きです。

どこへでも値を渡せるので、ここのページでも欲しいとなると、複数のコンストラクタ引数に値を渡すことがかっこよくないのかと思ってみたり(^_^;)

なので、Riverpodは使った方がいい。しかし保守もするアプリだとAsyncValueやStateを管理するロジックだけで使いそれ以外は、ストラテジーパターンとかCQRS(voidかreturnなだけな気がする)を使って頑張った方が良い。

もしフリーランスやSESの方だと現場を変えると文化が違う現場になると思うので、昔からあるお作法も知っておきつつモダンな技術構成であるRiverpod/freezed/Navigato2.0など押さえておきましょう。

👀最新のテクノロジーはウオッチしておこう

https://riverpod.dev/ja/docs/introduction/why_riverpod
https://pub.dev/packages/go_router_builder
https://pub.dev/packages/auto_route
https://pub.dev/packages/openapi_generator

Discussion