7
4

More than 1 year has passed since last update.

Ruby on RailsとReactでECサイト構築

Last updated at Posted at 2021-11-04

概要

Laravelで同じ実装をドメイン駆動設計(DDD)とMVCで比較してみた(フロントはReact)」の検証で実装したECサイトを、Ruby on RailsとReactに移植してみました。ただ、Laravel版はMVC、DDD、軽量DDDの3種類で実装していましたが、Ruby on Rails版はMVCのみで実装しています。目的はLaravelとRuby on Railsのアーキテクチャの違いを知ることと、そこで得た知見を今後のソフトウェア開発に活かしたい事だった為です。見た目も機能もそっくりそのままLaravel版と同じです(バリデーションだけ若干簡略化しました)。 Ruby on RailsとReact初学者の為、至らぬ点が多々あるのはご容赦下さい・・・

ソースコード

ミドルウェア

ミドルウェア バージョン
PostgreSQL 13.3
npm 6.14.12

フレームワーク・ライブラリ

フレームワーク・ライブラリ バージョン
Ruby 2.4.6p354
Rails 5.2.6
React 17.0.2
material-ui 4.12.3
typescript 4.4.4
sass 1.38.0

Ruby

Laravelで実装していた箇所は全面的にRuby on Railsの形で作り直しが必要でした。ただ、フレームワークのアーキテクチャがLaravelとRailsが似ているので、ほぼ文法の置き換えのみでいけました。

React

ReactはerbからReactを呼び出す部分だけ工夫が要りましたが、Laravel版で実装していたReactのコンポーネントはほぼそのまま使えました。変更が必要だったのは、Reactへの値受け渡し部分のみでした。LaravelではbladeからReactへ値を連携する際json文字列に変換し、Reactでそのjson文字からオブジェクトへとパースしてました。とこらがRuby on RailsではerbでReactに値を連携する際json文字列にせずに渡せて、Reactでもjson文字列をパースせずともオブジェクトとして受け取れている状態となっていました。内部ではRuby on RailsからReactへ値連携時にjsonへ変換してるとは思いますが、react-railsというgemライブラリのreact_componentという関数を使ったのでそこはブラックボックスで中で何をしているかは分かりません。

バリデーション

Laravel版ではFormRequestを使ってコントローラーに入る手間でバリデーションをかけていました。これはこれで便利なのですが、Ruby on RailsではActoveRecordにバリデーションチェックを実装する機構が用意されていてそれを用いました。ORMにバリデーションチェックの機能がついているのは非常に合理的だと感じました。理由は、FormRequestだと例えば商品詳細画面とカート追加APIで商品IDをバリデーションチェックする際、両方のリクエスト用に同じバリデーションを実装する必要が出てきます。一方ActiveRecordだと商品IDのバリデーションチェックはProductモデル一カ所に実装すればよく、実装の重複はありません。仕様変更の影響範囲も最小限になります。バリデーションチェックは、DBに近い層でやるActiveRecordのアーキテクチャが優れていると感じました。DDDの場合は商品IDのValueObjectへバリデーションチェックを実装する事で重複は避けられると思います。ただ、参考書籍「実践ドメイン駆動設計(Object Oriented SELECTION)」ではValueObjectへバリデーションチェックを実装するのは、ドメインモデルに責務を負わせすぎと言う記載が確かあったと思いますので、この辺は色々な議論はあるかも知れません。

ファイル数・ステップ数

Laravelと同じ事を実現するのに、Runy on Railsだと実装量が圧倒的に少なくて済みました。Laravel版と比べて2/3位のステップ数におさまりました。言語仕様の違いもありますが、Ruby on Railsではコンポーネントのパスやファイル名が決まっていて、それらを定義する必要が無いのもあります。必要な事は予め用意されていて、徹底的に実装効率を上げる事に配慮されたフレームワークなのだと感じました。その反面、ファイルパスの配備先やファイル名はルールが定められており、独自にカスタムする事は出来ません。また、Active Recordのjoinでは記述形式が独特の書式すぎて、どう書いたら目的のjoinができるのかがわかりにくかったです。言語仕様が実装量を少なくしようとしすぎているのか、はたまた実装スタイルのスマートさを過度に目指しすぎているせいなのか、書式が妙に難解になっている感があります。

種別 ファイル数 ステップ数
Laravel版(MVC) 23 725
Ruby on Rails版 19 471

パフォーマンス

ローカルのKubernetesの環境で実行する限りでは、体感ではキビキビ動いている用に感じました。ところが計測してみると、Laravel版と比較してRuby on Rails版は1.2〜8.2倍時間がかかっていました・・・まぁ7つの処理中5つが200ms未満だったので、許容範囲かなとは思います。ちなみにLaravelはPHP8ですがJITは無効。Rubyは2.4.6なのでJIT未対応バージョンでした。

機能 Laravel(MVC)時間 Laravel(MVC)メモリ Rails時間 Railsメモリ
商品一覧画面表示 118ms 2750KB 644ms 3064KB
商品詳細画面表示 20ms 703KB 163ms 40KB
カート追加API 77ms 646KB 90ms 20KB
カート画面表示 47ms 610KB 70ms 4KB
注文画面表示 26ms 610KB 112ms 0KB
注文バリデーションAPI 102ms 822KB 40ms 440KB
注文確定処理 193ms 1363KB 1399ms 8912KB

参考書籍

実践ドメイン駆動設計(Object Oriented SELECTION)

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4