ApexEloquent

「クエリ構築」と「クエリ実行」を分離する Apex 向けデータアクセス OSS。ドメインは Scribe でクエリの設計図を描き、IEloquent が実行を引き受けます。

Why ApexEloquent

クエリ構築と実行の分離Query Delegation Pattern

Salesforce 開発で広く採用される Selector Pattern は、クエリを共有でき、ビジネスロジックにクエリを書かずにメソッド経由でデータを取得できる利点があります。しかし長期運用では「ちょっと違うクエリが欲しい」たびにメソッドや変数を継ぎ足すパッチが繰り返され、徐々にそのシンプルさが失われていきます。さらに、テスト自体が DB を必要とする 結合テストしか書けない という制約も付いてまわります。

ApexEloquent は、Repository パターンを Apex のために再設計し、クエリの「構築」と「実行」を別々に行う Query Delegation Pattern を採用しました。ドメイン層は Scribe でクエリの設計図を描き、それを IEloquent.get(scribe) に渡すと、本番では Eloquent が SOQL を発行します。

テスト時は IEloquentMockEloquent に DI で差し替えるだけで、DB を介さない単体テストが書けるようになる、長期の開発を妨げないフレームワークです。

Domain
Scribe
クエリの設計図
Delegation
IEloquent
本番 / Mock を DI で切替
Execution
Eloquent / MockEloquent
実 SOQL / DB なし

Core Building Blocks

3 つのコア機能

Query Builder

Scribe

型付きでメソッドチェーンを積み上げる immutable なクエリビルダー。SELECT / WHERE / 並び替え / 集計 / GROUP BY / HAVING まで 1 つの API で組み立てます。各メソッドが新しい Scribe を返すので、同じ条件から件数取得用と一覧取得用のクエリを派生させるのも自然です。

使い方ガイド →
Data Access

IEloquent (Eloquent / MockEloquent)

Scribe を受け取って SOQL を実行するインターフェース。DML (insert / update / upsert / delete) も bulk のオーバーロード付きで統一的に扱えます。本番は Eloquent、テストは MockEloquent を Layered Constructor Pattern で DI 差し替え。

使い方ガイド →
Record Wrapper

IEntry (Entry / MockEntry)

SObjectAggregateResult を同じ get(field) で扱える統一ラッパー。MockEntry は数式・ロールアップ・親リレーション・auto-number といった書き込み不可項目も自由に設定できます。

使い方ガイド →

Why This Design

ApexEloquent の独自設計

非書き込みフィールド・親子・AggregateResult までモック可能

数式項目・ロールアップ・親リレーション・auto-number など、通常は書き込み不可な項目もモックでは自由に値を入れられます。親子の階層も、集計クエリの戻りも、同じ IEntry インターフェースで一貫してモックできます。

MockEntry Deep Dive を読む →

ORM 機能とモック機能の同時提供

多くの ORM ライブラリはクエリ構築までしか面倒を見ず、テスト時の DB レス化は別ライブラリや手作りモックの組み合わせが必要になります。ApexEloquent はクエリ構築から、ビルトインのモック機能で組まれた DB レスの高速な単体テストまでを、ノンストップで書き上げることができます。

MockEntry Deep Dive を読む →

モック注入時の SELECT 漏れもテスト段階で検知

本物の SOQL で取得した SObject は、SELECT していないフィールドにアクセスすると即エラーになります。ところがテストで SObject を注入するパターンでは、未取得フィールドへのアクセスがスルーされて単体テストでは気付けず、結合テストや本番で初めて表面化します。ApexEloquent は Scribe の SELECT 句を覚えていて、モック注入の場合でも未取得フィールドへのアクセスを 単体テスト段階で例外として 叩き出します。

SELECT 漏れの安全網 Deep Dive を読む →

Spy + failOn でリトライ系もテスト

Spy プロパティで、レコードの作成・更新・削除が正しく行われたかを DB レスで検証可能です。さらに failOn メソッドでは、エラーを意図したタイミングで投げることができるので、プロダクションコードを汚さずに catch ブロックの検証ができます。

データ取得と DML、IEntry、Mock を読む →

Deep Dives

設計の動機・独自機能を深掘りする

ApexEloquent がなぜこの形に至ったか、 他の OSS にない独自機能はどう効くかを、 5 つのドキュメントで掘り下げています。

Architecture

Query Delegation Pattern

Selector Pattern の長期運用課題から出発し、クエリ構築 (Scribe) と実行 (IEloquent) を分離する設計哲学を整理します。

Selector / Repository

Apex における Repository パターンの試行錯誤と内蔵化

Apex で Repository を愚直に書いたときの問題、Salesforce 公式の Selector Pattern との関係、ApexEloquent が IEloquent として「内蔵 Repository」 を提供する理由。

Migration

Apex の生 SOQL から、チェーンメソッドで組み立てる ORM へ

生 SOQL 中心の Apex 開発で支払っている代償 (可読性 / 動的条件 / 型安全性 / リレーション / テスト) を、Scribe + IEloquent でどう軽くするかを実例ベースで解説する移行入門。

Test Data

MockEntry: Apex のテストデータ作成を成立させる仕組み

書き込み不可項目 (数式 / ロールアップ / auto-number / リレーション名) と親子関係構築の困難という Apex のテスト 2 大課題を、MockEntry の override map / 専用ファクトリ / 集計結果モックでどう解決するか。

Independent Feature

モックテストの偽陽性を検知する: SELECT 漏れの安全網

「テストでは通って本番で落ちる」 タイプの偽陽性問題を、ApexEloquent が Scribe との連携で構造的に塞いでいる仕組みを、主オブジェクト / 親リレーション / 子サブクエリ / 集計エイリアスの 4 ケースで実証。他 OSS にない ApexEloquent 独自の安全網。

Where It Sits in Apex Stem

Apex Stem における位置づけ

ApexEloquent は Apex Stem を構成する 4 つの OSS のうち、Data Access を担います。Handler-Usecase Architecture の Usecase 層で DB アクセスを伴う際に登場し、テスト戦略 の「Usecase 単体テスト ↔ ApexEloquent」の対応を担う中核です。

ApexEloquent
Data Access: SOQL / DML + Mock
ApexBlueprint
Test Data Factory: 結合テスト用の実 DML データ生成
ApexTrace
Lifecycle Logging: Usecase の経路追跡とテスト検証
ApexTools
Foundation: TriggerHandler 基底 + HTTP DI ラッパー
関連ドキュメント

Start with the Developer Guide

開発者ガイドでは、Scribe でクエリを組み立てる、データを取得して DML を流す、リレーションを扱う、の 3 つの使い方を実際のコードで通します。API リファレンスも併せて参照できます。