概要
Java(Spring Boot)でレイヤードアーキテクチャを採用して開発してきたエンジニアが、
Ruby on Rails と比較したときの アーキテクチャ上の違いを整理した記事です。
Rails の爆速開発の仕組みとSpring Boot(レイヤードアーキテクチャ)の堅実さの違いを、自分用の整理としてまとめています。
- あくまで個人の経験に基づく比較であり、プロジェクトや設計方針によって異なる場合があります
- Spring Bootはレイヤードアーキテクチャだけでなく、クリーンアーキテクチャ、ヘキサゴナルアーキテクチャ(Ports and Adapters)など、他のアーキテクチャも適用可能です。ここでは、レイヤードアーキテクチャに特化して比較してみました
- Java、Railsどちらも好きな言語であり、ディスるつもりは無いです
対象読者は以下のような人を想定しています:
- Java / Spring Boot → Rails に移行するエンジニア
- Rails と Spring をアーキテクチャ視点で比較したい人
- Rails の "規約による開発スタイル" に興味がある人
1. 結論:Rails と Spring Boot の最大の違い
まとめると次の一言に尽きます。
Railsの主な特徴
Rails:ActiveRecord パターンを中心とした MVC フレームワーク である
※厳密にはAPIモードなども可能
Spring Bootの主な特徴
Spring Boot:レイヤードアーキテクチャがよく採用されるフレームワーク
※クリーンアーキテクチャ、ヘキサゴナルアーキテクチャ(Ports and Adapters)など、他のアーキテクチャも適用可能
主な特徴の違い
- モデルの役割
- 入力データの扱い方
- 層の分け方
- Data Transfer Object(DTO)の存在有無
2. Rails と Spring のアーキテクチャ思想
Rails の思想:MVC + ActiveRecord
Rails は「設定より規約(Convention over Configuration)」を前提とし、
MVC でアプリ全体をシンプルに構成する思想を持っています。
- Model(ActiveRecord)がテーブル構造、永続化、バリデーション、ドメインロジックを担当
- Controller は薄く、Model と View をつなぐだけ
- View は Model の属性を前提にフォームや画面構造を形成
- Service層などの追加レイヤーは標準では用意されていない
- Rails は 「Model に責務を集約する」 という思想が強く、初期開発のスピードが速い。しかし、大規模化すると Model が肥大化しやすい
- 実際には Concern、Service Object、Form Object などのパターンで責務分離する
Spring Boot の思想:レイヤードアーキテクチャ
Spring Boot は レイヤ(層)を明確に分ける構造が一般的です。
典型的には以下の 4 層:
- Controller(UI層)
- Service(アプリケーションサービス層)
- Repository(永続化層)
- Domain(Entity や DomainService)
レイヤ間のデータ受け渡しには DTO を使う
フォーム入力のための Form クラス を用意する
Spring Bootにおける DTO, Form, Entityの違い
責任分離が明確
"データの流れを層ごとに明示的に制御する" という設計が推奨され、Rails の標準構成よりも 責務分離が明確 の印象を持つ
3. Model / Entity の違いが決定的
■ Rails:Model(ActiveRecord)
Rails モデルは テーブルと 1:1 対応することが前提です。
class User < ApplicationRecord
validates :email, presence: true
has_many :posts
def full_name
"#{first_name} #{last_name}"
end
def activate!
update(active: true)
end
end
# 使用例
user = User.find(1)
user.activate! # 永続化もModelが担当
- テーブル名とモデル名が規約により自動対応
- カラムが属性になる
- 永続化(ORM)
- バリデーション
- コールバック
- ドメインロジック
Railsのモデルはレイヤードアーキテクチャと比較すると以下で定義出来るかもしれない
"Model = Entity + Repository + ドメインロジックを全部まとめたもの"
■ Spring:Entity
Spring(JPA/Hibernate)の Entity は テーブルにマッピングされるクラスですが、
永続化の責務は Repository に分離されています。
@Entity
public class User {
@Id
private Long id;
private String email;
private String firstName;
private String lastName;
public String getFullName() {
return firstName + " " + lastName;
}
public void activate() {
this.active = true;
// 永続化はRepositoryが担当
}
}
// 使用例
User user = userRepository.findById(1L);
user.activate();
userRepository.save(user); // 明示的な保存
- Entity はドメインモデルとしての役割が中心
- 永続化は Repository が担当
- バリデーションは別途 Bean Validation で実装
つまり、
Spring の Entity は永続化の責務を持たず、Rails の Model より責務が限定的
という点が大きな違いです。
4. DTO の存在と役割の違い
■ Spring:DTO がレイヤー間のデータ受け渡しを担う
Service → Controller → View といったレイヤー間で DTO を受け渡すのが標準的
- レイヤ間の境界を明確にする
- 表示用データを最適化する
- Entity の露出を防ぐ
■ Rails:Web画面のMVCではDTOは標準ではない
RailsのMVC構成ではDTOは標準ではないが、以下の仕組みが用意されている
- Serializer(ActiveModel::Serializers、Jbuilder、Blueprinter など)
- Presenter / Decorator
- FormObject
これらは必要に応じて導入しますが、
Springではレイヤー間の標準的なデータ受け渡しが標準であるが、Railsでは標準でない
5. Form(入力データ)の扱いの違い
■ Spring:Form クラスが "入力用 DTO"
- 入力画面用のクラス(Form)を作る
- Controller が Form を受け取る
- Service に DTO で渡す
画面入力項目を Entity から切り離して扱う のが一般的。
■ Rails:フォームは Model と密結合
Rails の form_with は Model の属性に依存するため、
<%= form_with model: @user do |f| %>
<%= f.text_field :email %>
<%= f.text_field :first_name %>
<%= f.submit %>
<% end %>
- 画面項目=モデルのカラム が強く紐づく
- 画面専用の Form クラスは "必要になれば作る" という文化
- ActiveModel を使えば FormObject も作れるが、標準的ではない
6. まとめ:Rails と Spring Boot の違い(表)
| 観点 | Rails | Spring Boot(レイヤード) |
|---|---|---|
| アーキテクチャ思想 | MVC + ActiveRecord パターン | レイヤードアーキテクチャは代表的 |
| Model / Entity | ActiveRecord(永続化含む) | Entity(永続化は Repository) |
| 永続化 | Modelが担当 | Repositoryが担当 |
| Service層 | ケースバイケースで使用 | 一般的に使用される |
| DTO | MVC では標準ではない | レイヤ間データ転送で使用 |
| Form | Modelと密結合 | 画面入力専用クラスを作成 |
| レイヤの分離 | 標準構成では弱い | 明確に分離 |
| 初期開発 | 非常に速い | 設計コストがある |
| 大規模化 | 追加パターンで対応可能 | 最初から分離されている |
7. まとめと所感
RailsとSpring(レイヤードアーキテクチャ) のアーキテクチャ思想、責務分離は全く異なる世界観と言える
主な違い
- Rails は ActiveRecord パターンで Model に責務を集約
- Spring はレイヤー分離と DTO による明示的なデータフロー
- Model / Entity の役割が根本的に違う(永続化の責務の有無)
- Rails は標準構成がシンプル、Spring は最初から責務分離
個人的な所感
- Rails は 規約で一気に開発スピードを上げる フレームワーク
- Spring は 責務分離を明確にして保守性を高める フレームワーク
- Rails の Model が肥大化しやすいのは事実だが、パターンで対応可能
- Spring は DTO や Form によってレイヤ境界がクリアで読みやすい
「Rails はアプリを素早く作れる」
「Spring はアプリを構造的に作れる」
そんな思想の差を感じています。
Spring 開発者が Rails に移行する際の注意点
- Service層がない: ビジネスロジックをどこに書くか迷う → Model か Controller、必要なら Service Object を導入
- DTO がない: レイヤ間のデータ受け渡しが直接的 → API なら Serializer を検討
-
Repository がない: Model が永続化を担当 →
user.saveで保存される - Form クラスがない: Model の属性がそのままフォームに → 複雑な入力は FormObject を検討
Rails を触り始めて違和感があった方の参考になれば幸いです。


