雑談用Shownoteの作成・共有サービスをつくった

チュートリアルじゃなくて、ちゃんと何か作って試しておかないとな〜という技術がたくさん自分の中で累積していたので、次のようなサービスを作って公開した。

shownotes.vercel.app

概要

雑談・1on1・リモート飲み会・勉強会などで、話したいネタを事前に作成・共有しておき、会話時には再生する形で1つずつネタを提示してくれる。

いまのところShownote自体の作成はGoogleログインを必要としているが、作ったShownoteの閲覧や雑談トピックの追加みたいなところはURLさえ知ってれば誰でもオッケーにしてる。

ログインしたらボタンを押せばShownoteの雛形が作れる。

f:id:mugi1:20210505225118p:plain

Shownote自体には自由に雑談テーマを追加できる。これはURLさえ知ってれば誰でもできるので、一緒に話したい人に事前共有しておける。

f:id:mugi1:20210505225358p:plain

実際に話すときは、追加順 or ランダム再生で、1個ずつトピックを表示してくれる。

f:id:mugi1:20210505225707p:plain

一応一定間隔でPollingしてるので、同じ画面を見ている人では表示が同期されるようになってる。5秒ほど開けてるので、同時に見ると少しラグとかズレがあるのは勘弁してほしい。websocketとか使えば良かったのだが、あんまりそのへんで頑張りたくなかったので雑にApolloClientでPollingとした。

f:id:mugi1:20210505230611g:plain
Pollingでなんとか同期している図

話してる時間をそれっぽく計測しているので、最後に一番盛り上がったトークテーマがどれだったかとかが表示される。

f:id:mugi1:20210505230454p:plain

なお一応公開しているが、使う人がいるかはわからなかったので現状以下の制約がある。

  • PostgreSQLがHerokuのフリープランなので10000レコードでサービスが死ぬ
  • アプリ自体がVercelにデプロイしてるので、DB接続で若干ラグがある

もし使う人がいるようであれば追々解消させる予定だが、誰もいなければ何もしない。

使った技術要素とそれらへの所感

次のようなものを使ってる

3画面しかないのに完全にオーバーキル構成である。 実現機能を考えればどう考えてもFirestoreとか使った方が10000000%良いのは最初からわかっていたが、これは仕事ではないので、そんなことより自分が勉強目的に使ってみたいモチベーションで使いたいものを全部入れた。問題はない。

Next.js

かなり昔のバージョンでチュートリアル的なことはやったことがあったが、改めてちゃんと何かを作ったのは始めてかもしれない。

普段Vueに慣れ親しんでいた身としては、ReactというだけでTS親和性が高くてとても良かった。また、next/image での画像最適化など、痒いところに手が届く感もあり、Vercelを使ったのでデプロイの簡単さも抜群だった。

一応部分的にSSRも採用したが、これは実際にプロダクション導入する場合は慎重に検討すべきところだな〜と改めて感じた。 Next.js側自体の推奨としても、認証が必要なページでのSSRとかはいらないよね??みたいな話もあったりするし、どうしても複雑化するので、サービスとして何を重視するのかとちゃんと向き合うのが最初にすべきことかもしれない

とはいえ、トータルの開発体験としてはとても素晴らしいものだった。新規で何か作るなら積極的に採用するよなぁというのも頷ける。

Prisma

今回このサービスを作った発端のモチベーションは「Prisma使って何か作ってみたい!!!」だったので、強引にPrismaを採用した。簡単に説明すると、Node.jsで動くORMです。

最近まで仕事でRailsを使っていて、今もRailsは好きなのだが、何が好きかというとActiveRecordの操作感に尽きるな〜と思ってる。(色々細かいことやりだすと大変なんだけども)

PrismaでのDB操作はかなりそれに近い感覚があり、prisma.user.findFirst(...) のような形でデータを取得できる。そして何よりも、それらを全てTypeScriptで型安全に操作できるのがとても良い。

また、現在はPrismaにはMigrationの仕組みが備わっていて、全体の主軸となる *.prisma に書かれたスキーマ定義をもとに、変更時には差分をMigrationとして抽出することができる。今回のような趣味レベルで使った範囲では特に困ることもなく動作したし、Migrationファイルの内容もただのALTER文が書かれているだけなので、SQL読める人なら内容も簡単に理解できて、編集しようと思えば編集できる。

全体的にかなり使いやすい印象。今後大きく流行っても全然不思議じゃない。

Nexus

APIはGraphQLにしたが、バックエンドにはNexusを使ってみた。

GraphQLでAPIを構築する際には Schema First か Code First の選択肢があるが、Nexusは Code Firstのフレームワークに該当する。

Schema First と Code First のどちらを良しとするかはサービスの規模感やチームの方針によって変わるため一概には判断できないと思うが、個人的には Code First のほうが全体の記述量が減ることが多いので好み。

ただ、Nexusにしたのは好みだけが理由ではなく、Prismaとの相性が良いのもある。 nexus-plugin-prismaというNexus用のプラグインが存在しており、たとえば「Bookモデルの中身を返すクエリ」を作るときに、Prismaが生成しているモデル情報をもとにレスポンスを定義することができる。

これの何が嬉しいかというと、DBが変わるとそれに伴ってNexusが生成するGraphQLスキーマも変化するので、そこからGraphQL Code Generatorを通せばクライアント側での型不整合なども全部チェックできるようになる。

なお、DBモデルをそのままクエリとして露呈するとか危ないでしょって最初は思ったが、公開するフィールドは明示的に指定したもののみに限定されるため、意図せず公開されるみたいなことは無く、そのあたりも問題なかった。

DB⇄APIサーバー⇄クライアントの全てが型定義で一貫してチェックされるのはとても快適で、DB変更時にクライアント側の変更が漏れたりするようなケースは開発中に一度も無かった。

Redux (Redux Toolkit)

Reduxをちゃんと使ったのは5年くらい前で、とてもツラかったような記憶があったのだが、Hooks対応なども経てとても良くなったと聞いたので試してみた。

結果としてはかなり使いやすくなってた。Redux Toolkitがとても良かった。昔Reduxでストレスに感じてたのは、やりたいことに対して手数があまりにも多すぎる点だったが、そのあたりが綺麗さっぱり解消されてる感覚があった。

これだけ使いやすいなら、下手にオレオレ状態管理するよりかは、何も考えずにとりあえずRedux採用したほうがトータルのコストは下がりそう。

まとめ

チュートリアルだけ過去にやった技術も多かったが、実際に小さいアプリケーションを作ってみることで得られる知見はとても多かった。モノを作って学ぶのは大事だな〜と改めて感じた。

ちなみに、今回のサービスのアイデアとしては「Clubhouseでのアジェンダ共有ができるといいかな〜」というのがあったが、先にClubhouseが瀕死になってしまった。

とはいえ中途半端で終わるのは悲しいので気合いで作り切った。完走するのは大事。

サービスとしては公開しておくので興味があれば使ってみてください。 https://shownotes.vercel.app/

不具合とか機能要望とかあれば @mugi_uno まで。

おわり