はじめに
このたび ApexEloquent v1.0 をリリースしました(GitHub / 開発者ガイド)。
今回は、なぜこのフレームワークを作ったのか、その背景をお話しします。
😵 「テストを書くのがこんなに大変とは…」
Salesforceで開発を始めた当初は、ApexからSOQLの発行がとても簡単に行えることに感動しました。
しかし実務でプロジェクトに関わると、現実はこうでした:
- すでに3年稼働している環境に多数のカスタムオブジェクトと複雑なリレーション
- 小さな変更でも、関連オブジェクトのテストデータを大量に準備する必要
- テストカバレッジが不足したコードが大量に存在
前任者が用意したTestDataFactoryを動かすと、データの挿入や更新トリガーがたくさん動き、テストデータの準備でガバナ制限に達するという有様でした。
正直、テストを書くのがあまりにも大変で逃げ出したくなることもありました
🔧 フレームワークを作るきっかけ
そんな状況の中で、「テストをもっと楽に書けないか」と考え始めました。
Salesforceに携わる前は Laravel を使った開発をしており、Eloquent ORM は非常に直感的で便利でした。
「Salesforce でもこんなふうにクエリが書けたら…」これが ApexEloquent の原点です。
最初は SOQL を動的に組み立てるライブラリとしてスタートしましたが、テストの問題は解決できませんでした。
そこにRepositoryパターンを導入することを考えましたが、Apexへの導入を考えた時にどうしてもスマートな導入が難しかったのです。
そんな時、Salesforce本体のプリンシパルエンジニアのJames氏のサイト「Joys of Apes」を見つけ、そこにあったDML Mockingの技術ブログを読み漁り、今のApexEloquentの概念が完成したのです。
そこから次々に実装を続け、非書き込みフィールドなど Salesforce 特有の壁も克服しました。
✨ ApexEloquentを作ったあと
ApexEloquentを使うことで
- 複雑なリレーションを簡単に記述可能
- 動的なクエリ追加による、コードの可読性向上
- 完全なモックによるテストサイクルのスピード向上 → テスト駆動開発のスピードアップ
- エッジケースから異常ケースまで、モックによるテストデータの準備が簡単になったことでたくさんのテストパターンを網羅→プロダクトの品質が向上
挙げきれないほどのメリットがありました。
ApexEloquentのコード例
子のリレーションを一緒に取得する
Accountの名前と一緒に、Emailを持っているContactのIdとEmailを取得する
Scribe scribe = Scribe.source(Account.getSObjectType())
.field('Name')
.withChildren(
Scribe.asChild(Contact.getSObjectType())
.fields(new List<String>{'Id', 'Email'})
.whereNotNull('Email')
);
// Generates: SELECT name, (SELECT id, email FROM Contacts WHERE Email != NULL) FROM Account
SOQLだとカッコの中が子のリレーションだということが判断できますが、ApexEloquentだとwithChildren()
があるので子のリレーションがあるのが一目瞭然です。
検索条件を動的に追加する
検索条件の入力があれば追加する
// 商品取得のベースクエリ作成
Scribe scribe = Scribe.source(Product2.getSObjectType())
.fields(productSelectFields)
.take(30)
.offset(offsetNumber);
// 商品名の入力があったら条件に追加する
if(!String.isBlank(inputProductName)){
scribe = scribe.whereLike('Name', '%' + inputProductName + '%');
}
// 商品タイプの入力があったら条件に追加する
if(!inputProductTypes.isEmpty()){
scribe = scribe.whereIn('Type', inputProductTypes);
}
このように条件を文字列でくっつける必要はなく、条件の追加が非常に簡単になります。
最後に
ここでは書ききれませんが、ApexEloquentはクエリの組み立てをサポートするだけでなくテスト駆動開発を強力にサポートする機能がコア機能として提供されています。
もしApexEloquentを使ったプロジェクト例や改善案があればぜひ教えてください!
リンク
ソースコードを読みたい方はこちら → github
開発者ガイドを読みたい方はこちら → KrileWorks