🚀

日記アプリ「ShareDiary」の技術スタックを公開します!

konnyaku2562023/01/20に公開

こんにちは、日記アプリ「ShareDiary」を個人で開発・運用している @konnyaku256 です。

ShareDiary は初公開から半年以上が経過し、アプリの動作や開発・運用フローが初期と比較して安定してきました。

この記事では、そんな ShareDiary の開発・運用を支えている技術スタックを紹介します。

ShareDiary とは

ShareDiary は複数の相手と日記を共有できる交換日記サービスです。
Android / iOS 向けのアプリを各プラットフォームのアプリストアで完全無料・広告なしで公開しています。

2022/04/07 に 初版となる v1.0.0 を公開してから、2023/1/19 現在までに4回のアップデートを行い、最新版の v1.4.0 が公開中です。
ここ数日の DAU(デイリーアクティブユーザー)は Android / iOS を合わせて 10 人程度なので、とても小規模・低負荷なサービスです。

関連コードの最初のコミットが 2021/04/29 なので、約1年の開発期間を経て公開に至り、約9か月の運用が継続中のサービスとなっています。

Android 版の主な画面のスクリーンショットを4つ掲載します。

ホーム 新規投稿 ドロワー 管理

ShareDiary を支える技術スタック

ShareDiary では開発のコア技術として、次の3つを採用しています。

  • Flutter(モバイルクライアント)
  • Hasura GraphQL Engine(GraphQL サーバー)
  • Auth0(認証)

サービスの主な要件となる「共有可能な日記」を実現するため、クライアントサーバーモデルを採用し、モバイルクライアントから認証のかかった GraphQL サーバーにリクエストすることで、権限を持つユーザーのみがリソースにアクセスできるようなシステムとなっています。

次のセクションから、項目ごとにより詳細な技術スタックを紹介します。

モバイルクライアント

Flutter

コア技術その1、Flutter です。

Flutter はモバイルアプリケーション開発のフレームワークで、Android や iOS といった複数のプラットフォームに対応したアプリケーションを単一のコードベースで開発することができます。

ShareDiary では後述する通知機能の OS ごとの設定など一部機能の実装を除いて、ほぼ全てのコードが共通化されています。
GitHub の言語比率ではリポジトリ中の Dart コードが全体の「93.8 %」を占めています。

後述する Auth0、Hasura と通信することで、認証した上でサービスのデータにアクセスします。

バックエンド

Hasura GraphQL Engine / Hasura Cloud

コア技術その2、Hasura GraphQL Engine および公式のクラウドサービスである Hasura Cloud です。

Hasura GraphQL Engine は 指定した RDBMS(PostgreSQL や MySQL)と接続してスキーマを解析することで、データの作成・読取・更新・削除に関する操作が実装された GraphQL サーバーを自動生成してくれるサーバーソフトウェアです。
Hasura を使えば、扱いたいテーブルとそのリレーションを定義するだけで、そのデータを操作可能な GraphQL サーバーを全く時間をかけずに実装できます。

ShareDiary では Hasura Cloud 上に開発および本番環境の GraphQL サーバーを構築し、認証やプッシュ通知を除くほぼ全ての API を開発・運用しています。
RDBMS は PostgreSQL を選択し、後述する Neon と接続しています。(開発開始時は Heroku の無料プランを使用していましたが、運用に入ってから歴史的経緯により、Cloud SQL、Neon と順に移行しました。)
このように、Hasura が API・DB などバックエンド全体の API Gateway として稼働しているイメージです。

Hasura Cloud には 0円/月 の無料プランがあり、ShareDiary では開発・本番環境ともに開発開始からずっと無料プランで運用しています。
https://hasura.io/pricing/

Neon

Neon はフルマネージドでスケーラブルなサーバーレス PostgreSQL クラウドサービスです。
ブラウザから Web Console にアクセスして SQL を直接実行できたり、DB のブランチ機能があったりと、MySQL における PlanetScale と似たような使用感です。

ShareDiary では、開発・本番環境ともに Neon の PostgreSQL を用いて開発・運用しています。
Hasura を使用している最中は PostgreSQL や Neon の存在を意識することは少なく、API の裏側になんとなく DB があるなという感覚で使用しています。

Neon には テクニカルプレビュー中の無料プランがあり、ShareDiary では開発・本番環境ともに Neon に移行してからずっと無料プランで運用しています。
※テクニカルプレビューが終了したら、無料プランがなくなる可能性はあるので、注意が必要です。
https://neon.tech/docs/introduction/technical-preview-free-tier/

Auth0

コア技術その3、Auth0 です。

Auth0 はメールアドレスとパスワードによる古典的な Web 認証から OAuth2.0、OpenID Connect、シングルサインオン(SSO)、多要素認証(MFA)といった最新の認証技術まで、様々な認証・認可方式に対応した認証プラットフォームのクラウドサービスです。

ShareDiary では、開発・本番環境ともに Auth0 を用いて開発・運用しています。
認証方式はメールアドレスとパスワードによる Web 認証にのみ対応しています。(本当はパスワードレス認証などにも対応したいのですが、無料プランでは利用できないため、実装を見送っています。)
前述した Hasura 側で Auth0 の JWT 形式の公開鍵を使用するように設定することで、GraphQL のエンドポイントに対して Auth0 の認証がかかるようにしています。
https://hasura.io/learn/ja/graphql/hasura/authentication/3-setup-env-vars-hasura/

Auth0 には 0円/月 の無料プランがあり、ShareDiary では開発・本番環境ともに開発開始からずっと無料プランで運用しています。
https://auth0.com/pricing

Flagsmith

Flagsmith はフィーチャーフラグとリモートコンフィグのためのクラウドサービスです。
ブラウザから Web Console にアクセスして、簡単に設定を管理できます。

ShareDiary では、開発・本番環境ともに Flagsmith を用いてフィーチャーフラグを運用しています。
具体的にはサービス全体のメンテナンス用のフィーチャーフラグを設定していて、任意のタイミングでサービス全体をメンテナンスモードに切り替えられるようにしています。
このフィーチャーフラグの値は Flutter によるモバイルクライアントから参照できるようにしています。

Flagsmith には 0円/月 の無料プランがあり、ShareDiary では開発・本番環境ともに開発開始からずっと無料プランで運用しています。
https://flagsmith.com/pricing/

Firebase Cloud Messaging / Cloud Functions

Firebase は認証やデータストアなどバックエンド開発のための機能がひとまとめになったクラウドサービスです。

ShareDiary には新しいページまたはコメントが投稿されたときにプッシュ通知を受け取れる機能があります。
この機能は、開発・本番環境ともに Firebase のうち、Cloud Messaging と Cloud Functions を用いて開発・運用しています。

Cloud Messaging は Android / iOS 両方へのプッシュ通知に対応しています。(iOS のほうは APNs(Apple Push Notification service)と FCM を連携することで利用できます。)
また、Cloud Functions は任意の JavaScript 関数をデプロイして実行することができます。

ShareDiary では、これらと Hasura Event Triggers を組み合わせて、プッシュ通知を実装しています。
Hasura Event Triggers では DB への操作イベントを起点にサーバーレス関数や外部 API を実行できます。
この仕組みを利用して、テーブルへの INSERT を起点に 通知対象のクライアントに対してプッシュ通知を送信するスクリプトが実装された Cloud Functions を実行し、Cloud Messagging を介して Android / iOS のモバイルクライアントに対して、プッシュ通知を送信しています。
Cloud Messagging でプッシュ通知する際、クライアントを特定するためのデバイストークンは事前にモバイルクライアントから取得したものを Hasura で保持しておき、これを Cloud Functions から参照して使うようにしています。

Firebase には 0円/月 の無料プランがあり、ShareDiary では開発・本番環境ともに開発開始からずっと無料プランで運用しています。
https://firebase.google.com/pricing

CI/CD

Codemagic

Codemagic はモバイルアプリのための CI/CD クラウドサービスです。
Flutter や Unity、ネイティブの Android・iOS など様々なプロジェクトがサポートされています。

ShareDiary では、Codemagic を用いてアプリストアへ提出するバイナリをビルドして、それをアプリストアへ自動的にアップロードしています。
具体的には、Codemagic とモバイルアプリの開発で使用している GitHub リポジトリを連携させて、Codemagic が提供している macOS インスタンス上でバイナリのビルドをしています。
また、Android では Google Cloud 上で Google Play API へのアクセス権を持つサービスアカウント、iOS では App Store Connect の App Store API key を使うことで、ビルドしたバイナリをアプリストアへ自動的にアップロードしています。

https://docs.codemagic.io/flutter-publishing/publishing-to-google-play/

https://docs.codemagic.io/flutter-publishing/publishing-to-app-store/

Codemagic には 0円/月 の無料プランがあり、ShareDiary では開発開始からずっと無料プランで運用しています。
https://codemagic.io/pricing/

onelink.to

onelink.to は単一の URL からのアクセスしてきた端末の OS などに応じて異なる URL へリダイレクトさせることができるクラウドサービスです。

ShareDiary では、onelink.to を用いてアクセスしてきた端末の OS がAndroid なら Play Store、iOS なら App Store、それ以外なら公式サイトの URL へリダイレクトされるようにしています。

onelink.to には 0円/月 の無料プランがあり、ShareDiary では運用開始からずっと無料プランで運用しています。
https://www.onelink.to/pricing

公式サイト

Next.js / Vercel

Next.js は Web アプリケーションを開発するための React フレームワークです。
また、Vercel は Next.js などのフレームワークによって開発された Web アプリケーションをホスティングできるクラウドサービスです。

ShareDiary では、公式サイトの開発・運用に Next.js と Vercel を用いています。
公式サイトは簡単なアプリの説明とアプリストアへのリンク、プライバシーポリシー・利用規約を設置しているだけの簡素なものなので、Next.js らしい実装は含まれていません。
公式サイトは本番環境のみ構築しています。

Vercel には 0円/月 の無料プランがあり、ShareDiary では開発開始からずっと無料プランで運用しています。
https://vercel.com/pricing

おわりに

いかがでしたか?
このように、ShareDiary では可能な限り時間とお金をかけずに開発・運用できるような技術スタックを採用しています。
Flutter や Hasura などの技術や Hasura Cloud や Auth0 などのクラウドサービスを活用することで、これを実現しています。
個人で、できるだけお金と時間をかけずにスマホアプリを開発・運用したい方の参考になれば幸いです。

サービス開発寄りの話は「個人開発でスマホアプリを作った話 | こんにゃくの日記」で書いたことがあるので、ご興味があれば覗いてみてください。

GitHubで編集を提案
ShareDiary技術ブログ

日記アプリ「ShareDiary」を開発・運用しています。 アプリの開発秘話や利用技術に関連する記事を投稿します。

Discussion

ログインするとコメントできます