Apex Stem をはじめる
•Apex Stem ドキュメント
Apex StemGet StartedIntroduction
Apex Stem の短い導入。書き直しは不要、最小の一歩から始められます。
Apex Stem は、Handler-Usecase アーキテクチャと、それを支える OSS 群でできています。何かを書き直す必要はありません。今日のコードを少しでも良くする最小の一歩から始めて、そこから育てていけます。
このページは短い導入です。本格的な移行手順が必要になったら、ページ下部のリンクから 4 ステップの完全ガイドに進めます。
コード例は ApexEloquent v2 以降で動きます。v3 では SOQL/DML の既定がユーザーモード (FLS を尊重) になっているため、実行ユーザーの項目権限にご注意ください。
得られること
- テストが本番より甘くならない。実 SOQL で取ったレコードは、SELECT していない項目に触ると例外になります。ところが、テスト用に自分で組み立てた SObject にはその検査がありません。テストのときだけ緩くなり、本番で初めて落ちます。ApexEloquent のモックは本番のクエリが何を SELECT しているかを知っているので、テストの段階で落ちます。
- 単体テストが数 ms で回る。DB に触らないので、org に Flow やトリガーが増えても速度が変わりません。速いから気軽に実行でき、フィードバックのループが回り続けます。
- 構造がそのまま見える。親子関係はインデントで書けます。クエリの組み立ても、テストデータの生成も、コードの形がデータの形になります。
- AI に渡す規約が軽い。アーキテクチャの宣言は 30 行ほどで書けます (実物は Handler-Usecase Architecture に掲載)。
CLAUDE.mdに常駐させても、他に読ませたいコンテキストを圧迫しません。 - 大規模な書き直しは不要。Usecase 1 つ、モック可能なクエリ 1 本ずつ進められます。
最初の一歩
今日ひとつだけやるなら、これです。いまインラインで書いている SOQL を 1 本、ApexEloquent の型付きビルダー Scribe 経由に通します。
Before
APEX
List<Account> accounts = [
SELECT Id, Name FROM Account WHERE Industry = :industry
];
After
APEX
Scribe accountScribe = Scribe.of(Account.class)
.field('Id')
.field('Name')
.whereEqual('Industry', industry);
List<IEntry> accountEntries = new Eloquent().get(accountScribe);
挙動は変わりません。変わるのは、テストから見たときのこの 1 本です。
- 差し替えられるようになる。テストでは
Eloquentの代わりにMockEloquentを注入すれば、DB に触らずにこのクエリの結果を決められます。 - SELECT 漏れが、テストで落ちるようになる。上の例は
IdとNameしか SELECT していません。もし後続のコードがIndustryを読んだら、その場で例外になります。素の SObject ならnullが返って静かに通り、本番で初めて気づくところでした。
これだけです。1 本ずつ進めれば十分。Usecase の切り出しやテスト層の追加は、準備ができてからで構いません。
補足: フィールドは
SObjectFieldではなく文字列 ('Id'、'Industry') で渡します。これにより、ビルダーは動的に組み立てられます。
さらに先へ進む準備ができたら
フルガイドでは、実際に動くコードとともに 4 つの段階的なステップを解説します。
- Scribe で SOQL を置き換える (上記をさらに展開)
- 結果を IEntry のまま扱う。早すぎる SObject 変換が罠になる理由
- Usecase を切り出す。Layered Constructor Pattern
- 適切な層でテストする。Usecase は MockEloquent、Handler は ApexBlueprint
→ フルガイドを読む
フレームワークを組織に入れる準備ができたら → Installing Apex Stem へ。コマンド1つの Unlocked Package と git submodule、2つの導入経路を解説しています。