Withings + React + FastAPIで自分の体重を自動で表示するアプリを作った

投稿日 2023-05-02
最終更新日 2023-11-18

こんにちは。ゴールデンウィークは休みたいので代わりに今日投稿します。今回は、以前作った体重表示アプリをReactに移し替えたのでそちらについて紹介します。
以前の記事はこちら
今回作ったもののGithubリポジトリは以下で公開されています。
https://github.com/matsunagadaiki151/withings-react
バックエンド側は別リポジトリにあります。(前回から少しだけ変わっています。)
https://github.com/matsunagadaiki151/withings-fastapi

作ったもの

IoT機能付きの体重計であるWithings Body+で計測した体重を折れ線グラフにして、可視化できるようにするアプリを作りました。
実際の画面を掲載します。

作った経緯

そもそもの理由については、以前の記事に記載しています。簡単に言うと「体重を計測したいが、毎日手打ちで記録するのがめんどくさかった」ということです。この時はStreamlitで作成していましたが、Reactを勉強したアウトプットがしたいということで、既存アプリのリプレイスを実施してみることにしました。

使用した技術

使用した技術は以下になります。

  • Python
    • FastAPI
    • requests
  • TypeScript
  • React
    • React Router
    • Redux Toolkit
    • react-chartjs-2
    • axios
  • Withings API
  • TailwindCSS
  • json-server

json-serverにはアクセストークン、リフレッシュトークン、アクセストークンの有効期限を格納するために利用しました。Streamlitの時はpickleで管理していましたが、React上でこれをロードする方法が分からなかったのと、今後DBに格納する修正があることを見越して利用してみることにしました。これに伴ってFastAPI側の処理が少し変わっています。
アプリの仕様は以下の通りになります。

  1. json-serverにアクセストークンが保存されているか確認する。
  2. アクセストークンが保存されていない場合、OAuth2による認可を行い、アクセストークンを取得するよう促す。
  3. OAuth2による認可、アクセストークン取得の処理はFastAPI側が行う。
  4. アクセストークンが保存されている場合、アクセストークンが期限切れでないかをチェックする。
  5. 期限切れでない場合は体重データを取得し、グラフを描画する。
  6. 期限切れの場合、リフレッシュトークンを用いてアクセストークンを再発行する。発行後、体重データを取得し、グラフを描画する。

技術スタック図も貼っておきます。(以前の記事のStreamlitをReactに変え、json-serverを足しています。)

雑記

以下、実際にこれを作った感想などを雑にまとめました。

想像以上に時間がかかった

上の画面を見ての通り非常にシンプルな画面です。そのため、すぐできるだろうと思っていましたがTypeScriptとReactの経験が浅すぎて40時間ほどかかってしまいました。特に時間がかかったのが、OAuth2による認可の処理です。axiosでFastAPIを呼び出して認可とアクセストークン発行を行うのですが、非同期処理周りの知識が薄いあまりに実装に時間がかかってしまいました。認証まわりが大変という声がよくわかりました。(Firebase等を使えば早かったかも?)

立ち上げるローカルホストが3つに増えた

以前から、FastAPIとフロントエンドで2つのローカルホストを立てなければいけなかったのですが、今回はそれに加えてDBに該当するjson-serverが増えました。そのため、自分の体重を手軽に見たいから作ったのに、ローカルサーバーを3つ立てなければならないという謎の現象が発生しています。
当然、シェルスクリプトやDockerを使えば解決するのですが、せっかくなので少し別の方法で解決しようと思っています。この辺りは後日ブログに書きます。

今回は以上になります。想像以上に大変でしたが、TypeScriptやReactの文法、OAuth2に関する基礎知識等はかなり身についたと思います。