Skip to content

Laravel 13 の「破壊的変更ゼロ」を踏まえた next-poc 方向性の再評価 — Illuminate API 流継承 Adapter vs next-poc 委譲 Adapter #59

Description

@nanasess

背景

2026 年 3 月、Laravel 13 が 「破壊的変更ゼロ」 を看板にリリースされた (Release Notes)。Laravel は Symfony component の上に独自の Illuminate API を被せた構造を 2013 年から維持しており、Symfony 7.x への乗り換え時点でもアプリ層に破壊を伝播させていない。

一方 next-poc は 2023 年から、Symfony / Doctrine に対する Eccube\* Adapter 層を後付けで導入する PoC を進めている (PR #41#58 系)。両者は 同じゴール (上位 framework の安定 API surface を保ち、下位 framework のメジャー破壊を吸収する) を目指しているが、実装パターンと現在地は大きく異なる

本 issue では Laravel 13 の達成を踏まえ、next-poc の方向性が依然として正しいかを技術的に検証し、改善余地を明確化する。

両アプローチの整理

Illuminate API (Laravel) — 継承ベース Adapter

  • Illuminate\Http\Request extends Symfony\Component\HttpFoundation\Request
  • 公開 API は input(), validate() 等、Symfony の語彙とは別物
  • Illuminate\Contracts\* は Symfony interface と signature が 意図的に divergent
    • 例: Authenticatable::getAuthIdentifier() vs UserInterface::getUserIdentifier()
    • 例: Dispatcher::dispatch($event, $payload, $halt) vs Symfony dispatch(object, ?string)
  • Symfony 6.0 で UserInterface::getUsername() が削除されても、Authenticatable には元から存在しないため影響ゼロ

next-poc — 委譲ベース Adapter

  • Eccube\Http\Request$adaptee として Symfony Request を保持
  • 公開 API は現状 Symfony 構造を 1:1 で再公開 (public InputBag $query; 等 6 つの Bag)
  • Eccube\EventDispatcher\EventDispatcher は Symfony EventDispatcher を委譲 (これは divergent な作り)
  • PurchaseFlow, QueryCustomizer, EccubeNav 等の EC ドメイン特化抽象を独自に保有

メリット・デメリット比較

評価軸 Illuminate next-poc 解説
Symfony 互換性 (is-a) △ (詰め替え必要) Illuminate は Symfony component にそのまま渡せる
Symfony major 吸収 ◎ (実績 10 年+) ◎ (理論上) 両者とも吸収可能。Illuminate は実証済み
final 化耐性 継承は Symfony 6.x 以降の final 化進行に脆い。委譲は無影響
Symfony 離脱の余地 × 継承から逃れられない vs $adaptee 差し替え可能
新機能の自動取り込み △ (手作業) 継承の恩恵 vs 明示再公開
メモリ・実行コスト 委譲は 1 ホップ増
テスト容易性 委譲は mock しやすい
API surface 制御 委譲は意図して絞れる
コード量 メソッド再宣言の保守工数
境界面の摩擦 Symfony 製 bundle (Form, Security, KnpPaginator 等) との往復コスト
レガシー retrofit N/A next-poc の主用途
設計の枯れ具合 ◎ (10 年+) △ (3 年, 進行中) 経験差
EC ドメイン親和性 PurchaseFlow 等の特化抽象を入れやすい

Illuminate アプローチの代表的な落とし穴 (参考)

→ 継承ベース Adapter は 毎メジャーで小さな地雷を踏む。Laravel はこれを 10 年かけて踏み抜いて現在地に到達している。

Laravel 13 が「破壊的変更ゼロ」を達成できた本質

抽象化の パターン ではなく、API surface の divergence が本質である:

  1. Symfony の API 形状から 意図的にズレた自前 surface を公開している
  2. Illuminate\Contracts\* が Symfony interface の 1:1 mirror ではない
  3. Symfony の class 階層 / interface 破壊が、divergence 層内に閉じ込められる

next-poc が同じ達成を狙うために必要なのは「委譲を継承に変えること」ではなく、「公開 API を Symfony 語彙から切り離すこと」

next-poc の現状評価

良い点

  • 委譲ベース選択は将来戦略的に正しい:
    • Symfony 6.x 以降の final 化進行に対して耐性
    • Symfony 離脱の選択肢を長期的に保持できる
    • 既存レガシーへの段階的 retrofit と相性が良い
  • EC ドメイン特化抽象 (PurchaseFlow, QueryCustomizer, EccubeNav 等) は Laravel にも Sylius にもない独自軸。EC framework としての差別化要因
  • Eccube\EventDispatcher\EventDispatcher は API surface が Symfony と divergent で、目指すべき形のお手本

課題

  1. API surface が Symfony 構造を 1:1 mirror している箇所が残る
    • Eccube\Http\Request::$query 等の public プロパティが Symfony InputBag を露出
    • Eccube\ORM\QueryBuilder のメソッド名が Doctrine と同一
    • → Symfony / Doctrine がこれらを変えると next-poc 利用者にも届く
  2. Eccube\Contracts\* interface 名前空間が存在しない
    • 現状 Adapter は具象クラスのみ
    • プラグインが具象に依存すると Symfony 離脱時の差し替え余地が失われる
  3. 境界面の詰め替えポリシーが未整備
    • Symfony 製 bundle (Form, Security, KnpPaginator) との往復で $adaptee を取り出す箇所が散在
    • 詰め替え箇所を 1 箇所に集約する方針が必要
  4. プラグイン作者から見ると毎 PR が breaking change
    • use Symfony\…use Eccube\… の書き換えが連続
    • 後方互換エイリアス (Laravel の VerifyCsrfToken 流) の戦略がない
  5. メジャーリリースのカデンスが不明
    • Laravel は年次の予告可能な変更で追従コストを平準化
    • next-poc がいつ 4.x / 5.x として切り出されるかが見えないと plugin author が動けない

提案 — Laravel 13 の達成から学ぶべき具体策

  1. Eccube\Contracts\* 名前空間の新設
    • 委譲 Adapter は実装。プラグイン/Customize は Contracts に依存させる
    • Eccube\Contracts\Http\Request, Eccube\Contracts\Auth\Customer, Eccube\Contracts\ORM\EntityManager
  2. 公開 API を Symfony 語彙から divergent に再設計
    • Eccube\Http\Request::$query (public プロパティ) → getInput($key), getJson($key) 等の EC 語彙
    • Eccube\Security\Customer::getMemberLoginId() 等で UserInterface::getUserIdentifier() rename を吸収
    • Symfony Request の 100 メソッドを全部 wrap せず、EC で使うサブセットを意図的に選別
  3. 境界面の詰め替えを toSymfony() 等の明示メソッドに集約
    • $adaptee への直接アクセスは internal とし、外部公開しない
  4. 後方互換エイリアス戦略の導入
    • 削除する Symfony 名前空間 use 文に対して、@deprecated alias を一定期間残す
    • Laravel の VerifyCsrfTokenPreventRequestForgery
  5. メジャーリリース・カデンスの明示
    • 「next-poc を 4.x / 5.x として切り出すタイミング」「Symfony / Doctrine 最低バージョン引き上げ計画」をロードマップ化
  6. マッピング戦略の再評価 (関連: Doctrine ORM 3.x で Doctrine\ORM\Mapping attribute が正規 2 択の片方に)
    • Core entity は XML mapping で Doctrine 依存を Entity class から剥がす選択肢を検討
    • Customize / Plugin entity は attribute 継続
    • EC ドメイン特化 attribute (#[Searchable], #[Personal], #[AuditLogged] 等) は追加で持つ
  7. AI 親和性を framework 化の目標に含める
    • Laravel Boost (MCP) / Laravel AI SDK は 2025–2026 の到達点
    • 安定した自前 API surface + 宣言的拡張点 (PurchaseFlow / QueryCustomizer) は AI による EC カスタマイズ自動化 の基盤として価値が高い

結論

next-poc の 委譲 Adapter という選択は今でも正しい (Symfony final 化耐性 + 離脱余地 + レガシー retrofit 適合)。ただし Laravel 13 の達成は パターン選択ではなく API surface の divergence 設計 から生まれている。

next-poc が同じ収穫期に到達するために必要なのは、

  • 委譲を継承に変えることではなく
  • 公開 API を Symfony / Doctrine 語彙から 意図的に切り離す設計 に踏み込むこと、

そして EC ドメイン特化抽象 + AI 親和性 という Laravel が持たない差別化軸を太らせること、である。

3 年で Laravel が 13 年かけた地点に並ぶことはできないが、「EC framework として AI 時代の DX を提供する基盤」 という独自ゴールに向かう道筋は十分妥当である。

参考

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions