Remixを試すために作ったTwitterのクローンアプリです。 ユーザーをフォローしたり、フォローしているユーザーのツイートを表示する機能があります。 画像をアップロードして、プロフィール画像を更新することもできます。 ツイートへの返信をまとめて表示する機能や、メールアドレスとパスワードでログインする機能もあります。
この頃から、TypeScriptをフルスタックで使うことに興味を持ち始めていました。 RedwoodJSとRemixのどちらかを試そうと思い、両方のチュートリアルをやりました。 RedwoodJSはCLIでCRUDのテンプレートを生成することができ、フルスタックFWっぽくて便利そうだなぁと思ったのですが、 生成されるファイルの型が微妙でTypeScript Firstではないように感じたので、Remixを試すことにしました。
RemixはNext.jsとは違い、バックエンド側の機能もある程度充実しているように見えました。 セッション情報をcookieに詰めるためのAPIや、ファイルをアップロードするためのAPI、 multipart formdataをパースするためのAPIなどがありました。
Prismaを本格的に使い始めたのもこの頃だったと記憶しています。 これまではRDBの一つのテーブルが一つのオブジェクトに紐づいているようなものが多く、直接Prismaのfind関数を使用してデータを取得していました。 複数のテーブルから一つのオブジェクトを作る場合、その変換を何度も書く必要があったため、find関数をラップして使用しています。
Prismaはデータを取得するfind関数に、whereやselect、includeなどのプロパティを含めたオブジェクトを渡すことで条件を指定できます。 これが、find関数をラップするうえでとても便利だと感じました。 例えばselectは指定できないがwhereは指定できるという制約を、Prismaが生成した型を使用して簡単に実現することができます。 他にも、Prismaのfindに渡すselectなどが含まれたオブジェクトから、findが返す型を事前に取得することもできます。 このプロジェクトでは、この型を関数の引数として受け取って、結果としてモデルの型を返すような変換関数を作っています。
認証をある程度自分で実装したのもこのプロジェクトが初めてでした。 Googleログインなどではなくメールアドレスとパスワードの認証を実装しており、 Remixのドキュメントに従って、cookieにセッション情報をすべて保存するような実装を行っています。
Prismaを使ってバックエンドを書くときの自分なりの設計が固まった気がします。 Prismaが生成したモデルの型をそのまま使うのではなく、自分でモデルの型を書いて、 それを手動で変換するためにラップしたfindを使うという設計です。 これ以降のプロジェクトでもこの設計がベースになっています。