ざっくり概要
生活していて日々出ていくお金の分析をしたかったので、家計簿アプリを作りました。
今回作ったアプリで譲れなかった要件は、ざっとこんな感じです。
- 基本的なデータの登録・削除・編集機能
- 複数端末(PC・スマホ)から触れること
- 楽天の利用履歴(楽天Payやクレジットカードを想定)と連携できること
趣味で作っただけなので、細かい設計はしてません。とにかく手を動かそうという発想で始めました。
WebアプリにしてDBを使わなければいけないのはいいとして、まず要件にある楽天の利用履歴うんぬんの話ですが、これは楽天で決済した際に送られてくるメールを分析してDBに取り込むというものです。
私個人はGmailを使ってますので、Gmailを分析できればいいやとなりました。
以下、このアプリを作る上で考えたこと、苦労したこと、完成したものについて述べます。(コードについては触れません。考え方のみです)
第1弾:GASで作ってみようの巻
一番最初に思いついたのは、GAS(Google Apps Script)を使うという手法です。
実際に、ドライブ上のスプレッドシートにWebアプリからアクセスして家計簿情報を記録するという方法でアプリを作ってみました。Googleのサービスなので簡単にメールとも連携できていい感じでした。
しかし、しばらく使っていく中でどうしても看過できない欠点がありました。
それは、、DB(スプレッドシート)へのアクセスが遅い!
少しの書き込みをするにも5~10秒程度待たなければいけないような状況です。
どうしたら早くアクセスできるかと考えて、AWSを使ってみようという結論に至りました。
第2弾:AWSで作ってみようの巻
家計簿のデータ自体はDynamoDBに保存しており、Webアプリ(TypeScriptで記述)からSDKを通してDBにアクセスします。
GAS時代と比べると、DBへのアクセスは格段に速くなりました。1秒あれば書き込みが終わります。これでDBについてのストレスはなくなりました。
一般的な家計簿アプリから少し踏み込んだ内容である楽天決済の連携については、先ほども申し上げた通りGmailの本文を分析してデータを登録しています。EventBridgeを用いて毎日夜中にバッチ処理を走らせ、DBに明細情報を自動で追加するような設計としています。
また、以前は作成したWebアプリのURLを開くと直接サービスが利用できるような状態でしたが、せっかくAWSを使うようになったのでCognitoと連携してログイン認証ページを通過してからでないとサービスを利用できない設計にしました。
基本的にこのサービスを使用するのは私だけなのですが、ログインページを作ったことで架空の明細情報なども入力できるようになりました。自分が作ったサービスを紹介するハードルが下がります(笑)
次に、完成したアプリについて画像とともに簡単にみていきます。
以下の画像のように、日ごとに明細情報(タイトル、金額、支払方法、カテゴリー)を記録できます。各レコードは裏で一意の識別番号を持っていますので、画面に表示される項目がすべて同一のレコードも当然区別できるようになっています。
またこのように、月ごとに明細を集計してどのカテゴリーにいくら使ったか表示できます。これはDBからのデータの取得時に集計を行い、グラフライブラリを用いて表示しています。
苦労したこと
まず今回は、TypeScript&Reactという今まで使ったことのない言語やライブラリで開発を始めたため、その仕組みの部分を理解するのがなかなか大変でした。とはいえWebアプリを開発するうえでは知っておいた方がいい部分でもあったと思うので、勉強してよかったです。その点ではAWSについてもまったく触ったことがなかったですが、一つアプリを作るだけでも以前よりはだいぶ理解が進み、自分にとってはブラックボックスだったところに少しずつ白が混ざってきました。
また、Gmailとの連携の部分も意外に大変でした。GASではまったく何も考えなくても完成してしまうぐらい簡単に連携できたのですが、外部のサービスからのAPI連携は本文へのアクセスの仕方などでちょっと工夫がいりました。
フロントエンドの基本的な部分は、Webサイトを作ったことが何回もあったのであまり苦労しませんでした。
今後の目標
現在のところ、データの編集や表示に関わる操作をするときにはDBから全件取得を都度行っています。しかしDynamoDBの制約で、APIをたたくとき一度に取得できるデータ量が1MBまでと決まっているようですので、レコードがどんどん増えた時にどうやって取得しようかと考えているところです。月ごとの金額の推移を表示しなくていいのなら、月ごとに取得するような方法もあるかと思いますが、わりとマストな機能ですのでそういうわけにもいかず、、
あとそれに関連する点として、今のままだとデータ件数が増えるほど編集や表示に要する時間が増えていきますので、AppSyncあたりを活用してWebアプリ読み込み時に一度だけ全件取得してあとは部分的に更新みたいな方法ができないかというのを考えていきたいです。(全然使ったことがないのでトンチンカンなことを言ってるかもしれませんが笑)