starfish

I'm Multistack Engineer.

railsからフロントエンドをひっぺがす

2021-05-01rails

railsからフロントエンドをひっぺがす

はじまり

  • react-railsを使っていた
  • プロダクトリリース初期の構成
  • 人数が少なかったので何も問題はなかった
  • プロダクトが大きくなり、人数も増えてきて問題が出てきた

構成

移行前

  • ElasticBeanstalk

    • rails
    • react-rails
  • RDS

移行後

  • ElasticBeanstalk

    • rails
  • CloudFront

    • S3
    • React
  • RDS

問題

  • フロントエンドだけリリースしたい場合に、バックエンドの修正が入ってきて、結果的に動作確認やビルドに時間がかかる

    • 特にrailsのasset:precompileに時間がかかる。15分とか普通にかかる。
    • その度にhotfixするのも面倒
    • 1回のリリース単位が大きくなってしまう

メリット/デメリット

メリット

  • リリース単位を小さくすることができる

    • バックエンド、フロントエンドそれぞれ単独でリリースすることが可能になる
    • 1回のリリースの単位を小さく細かくして、リリース回数を増やす運用にしたい
    • リリース単位が大きいと、問題が発生した場合の原因究明に時間がかかりがちなのと、戻す単位も大きくなってしまう
  • バックエンド、フロントエンドが別々の環境で動作するので、問題発生時の影響範囲を小さくすることができる

    • 同じ環境で動いていると、バックエンドの負荷が高くなるとフロントエンドのロードも遅くなる
    • サーバーが落ちるとシステム全体がダウンしてしまう
    • 環境を分けておけば、APIサーバーが落ちていたらフロントエンド側でエラー画面を出すことが容易になる

デメリット

  • APIのバージョン管理を厳密に行う必要が出てくる

    • リポジトリが同じであれば、APIの修正に伴うフロントエンドの破壊的変更を事前に察知することが比較的容易
    • APIの破壊的変更、利用しているAPIの管理が重要になってくる
    • commit messageに major/minor/patch を入れ、リリースタグなどでSemantic Versioning等での管理を行うことで解決

やった事

gemをひっぺがす

  • 認証用のAPIを別途用意

    • deviseにフル依存していた
    • バックエンドとフロントエンドが別ドメインで稼働するので、deviseのsessionを利用することができない
    • 認証用のAPIを別途用意して、バックエンドからSet-Cookieを利用してフロントエンドにアクセストークンを渡す
    • SecureとHttp-Onlyを指定することで、スクリプトからアクセスできないようにする
  • railsのviewを利用していた箇所をひっぺがす

newフロントエンド用のリポジトリを用意

  • 元々のフロントエンドのコードを別リポジトリへ退避
  • 別ドメインで稼働するように環境構築
  • APIのCORS設定で、新旧どちらのフロントエンドのドメインでも利用できるようにする
  • リリース時にbuildしてS3にファイルをpushして、CloudFrontのキャッシュをクリアする仕組みを用意

ドメイン切り替え

  • APIサーバ用のドメインを発行して環境を新規で用意する
  • 新フロントエンドから実行するAPIのドメインを切り替える
  • 既存のドメインを新フロントエンドのCloudFrontへ向ける

結果

  • バックエンド、フロントエンドともに、平均して1日に1回のリリースが容易になった

    • 分割前は1週間に1回がやっとだった
  • リリース前のビルド時間が速くなった

    • 分割前は平均して15分から20分程度かかっていたが、分割後は5分から8分程度で終わるようになった
  • フロントエンドの表示速度があがった

    • EC2に置いていたファイルに直接アクセスさせていたものをS3 + CloudFrontへ移行させたため

所感

  • チームメンバーの人数が少なく、プロダクトの利用者も少ないのであれば、react-railsを利用してリポジトリを1個にして同じ環境で動かすのが楽

    • APIのバージョン管理や、用意する環境も少なくて済む
  • チームメンバーが増えてメンバーの専門性が上がり、プロダクトの利用者が増えてきたら今回のような対応を入れてバックエンド、フロントエンドを分割した方が良い