RailsアプリをNext.js+Rails API + GraphQL(Relay)にリプレイス(snowwshiro | スノーしろ)
2019年12月より運営している「snowwshiro|スノーしろ」は、Ruby on Railsアプリとして開発していましたが、今後の開発効率化を図る為、フロントエンドとバックエンドを分離することにしました。
そして今月(2021年12月)にリプレイスが完了しましたので、今回採用した技術スタック等についてご紹介します。
リプレイス後のサイトは以下となります。
フロントエンド
Next.js
フロントエンドにはNext.js(React)を使っています。
普段関わっているお仕事でNext.jsを触ることが多かったので、そこで得たものを活かせる様にしたいと考えて採用しました。
TypeScriptを使っています。
Relay
後述のGraphQLサーバーとのやりとりを担うクライアントライブラリとしては、Relayを採用しました。
現在最もメジャーなのはApollo Clientと思われますが、Next.js(React)を使用すること、将来的にReact Nativeの利用を想定していること、Facebookが開発しているのにマイナーなライブラリなのは何故だろう?という興味から、Relayを選びました。
技術的はメリットについては、以下記事を参考とさせて頂きました。また、著者のwawoonさんが管理している「GraphQLを使っている人たちの集まり」Slackチャンネルでも質問させて頂きました。
GraphQL(特にRelay)に関する情報はまだまだ少ないので、非常に助かりました。
Recoil
こちらもお仕事で触ったことがあるものを採用しました。
最もメジャーなのはReduxかと思いますが、実はそちらは触ったことがありません💦
複雑な状態管理はまだ行わないこと、Recoil自体がシンプルで使いやすいことから、そのまま採用しました。
その他のライブラリ(詳細は省略)
- css modules
- sass
- ress(リセットcss)
- React Hook Form
- nprogress(プログレスバー)
- React Hot Toast(トースト・アラート)
- React Infinite Scroller
- React Loader Spinner
- React-Tsparticles(トップ画面の雪描写)
バックエンド
Rails(APIモード)
Ruby on Railsで構築したものを活かすか、それとも関わることが多くなったFirebaseに移行するか、かなり悩みました。
サービスとしてはまだ途上とはいえ、本番環境にそれなりのデータもあり、そのデータ移行(PostgreSQL→Firestore)やロジックの書き直しを考えると、かなりのハードルを感じました。
一方で、少しでもバックエンドの開発を効率化したい気持ちもあったので、試しにGraphQL Rubyを使ってみたところ、かなり良い感触を得られたので、バックエンドはRailsをAPIとして使うようにしました。
結果的に現状この選択は正解だったと感じています。かなりのロジックをそのまま使えたので、目標としていたリプレイス時期に間に合わせることが出来ました。
GraphQL Ruby
既存のRailsアプリにgem graphqlを追加し、GraphQLサーバーとして改修しました。
途中の作業はGraphQL Rubyの仕様の理解に苦労しましたが、エンドポイントが固定でルーティングを気にしなくてよいこと、Modelのvalidation等は大半がそのまま使えること等がとても有難かったです。
認証・認可
Firebase Authentication
認証・認可をどうするかは非常に悩みました。Railsのdeviseをそのまま使うことも選択肢でしたが、deviseを使いこなせている感触が得られておらず、出来れば卒業したいという気持ちが強かったです。
そこでこれも最近よく利用していたFirebase Authenticationについて調査し、どうやらRails APIと連携して使えそうだということがわかったので、実際に扱ってみました。
deviseでの情報をエクスポートしFirebase Authにインポートしてみる、インポートしたアカウントにNext.jsからアクセスしてRails APIで認証をチェックする等を試してみて、構築できそうな手応えが得られたのでFirebase Authenticationを採用することとしました。
本番環境のデプロイ
フロントエンドはVercel
Next.jsはVercelにデプロイしています。
当初はFirebase Hostingを使っていましたが、思ったようなパフォーマンスが得られなかったので、素直にVercelに切り替えました。
商用につきProプランとなることが懸念でしたが、コストに見合うパフォーマンス・開発体験は得られているので納得しています。
バックエンドはHeroku
リプレイス前と同様に、Rails APIはHerokuにデプロイしています。
これも日頃から使っているというのが理由です。但しこちらは要検討事項として後述します。
その他に利用しているサービスなど
- Stripe:決済・ホストへの支払(connect)
- SendGrid:メール配信
リプレイスの作業期間
2021年7月頃から本格的な作業を開始し、2021年12月9日にリプレイスが完了しました。
リプレイスを経ての所感
こちらでは、上記リプレイスを経て感じた私の所感を残します。
良かった点
- サービスの質の向上を図る上で、Next.jsの環境に移行できたことは大きいと感じています。メインで扱っている技術を採用出来たことで、UI開発の効率・開発意欲が高まりました。
- GraphQL・Relayでの開発環境は、環境構築や仕様の理解がかなりのハードルではあります。正直エラーとの戦いを繰り返しましたし、「ファイルのアップロードはどうするの?」「ページネーションは?」と、一つずつ山を越えていくことの連続でした。その先に得られた開発環境は非常に快適で、10月前後からは開発が加速化した感じがします。
今後の課題
- イベントページ関係で使っているSSRの反応が要改善と感じています。Next.js/Vercel 環境なのでISRを活用することも検討していますが、イベントページはホストが編集することがあり、リアルタイムに反映できないことをどう消化するかが課題です。消化できないとすれば、Herokuからの移行(GCP又はAWS)を想定しています。
記事について
今後はこのリプレイスにて触れた技術について、随時記事にしていきたいと思います。
個人的には情報の少ないRelayに関して記事にしていきたいと考えていますが、コメント・リクエスト等頂ければそちらを積極的に記事にしていきたいと思います。
コミュニティの紹介
最後に、私が日頃お世話になっているエンジニアコミュニティについて、リプレイス達成の感謝と共にご紹介します。
雑食系エンジニアサロン
エンジニア系YouTuber|雑食系エンジニアの勝又健太さんが運営しているサロンです。
プログラミングを学習し始めた2019年にちょうど立ち上げされていて、興味本意で入会して以来お世話になっています。
Web系エンジニアを目指す方向けのサロンですが、経験豊富なエンジニアからのコメント付き情報共有があったり、現役エンジニアにも有益かと思います。
CodeQA
私のエンジニアとしてのメンター・師匠・先輩である米本剛士さんが運営しているコミュニティです。
Rails、React・Next.js、どちらも米本さんのメンタリングによって習得しました。
リプレイスに当たっては、方向性の相談やステージング環境でのテスト等で米本さんとメンバーにご協力頂きました。
ご拝読ありがとうございました。
Discussion