モダンSalesforceアプリケーション開発 DX編

Salesforce DX向上委員会によるプラットフォーム愛護週間の記事です。

## Salesforce組織における開発の問題点

Salesforceでシステムを作る際の良い点というのは、ほぼエンドユーザのような非エンジニアでもポイント＆クリックでカスタマイゼーションできてしまうところです。もちろん、エンジニアであっても、UIで作業をしてそのままプロトタイピングできるというのは大変効率の良いものです。

ただ、もちろんこれは諸刃の剣であって、一般的なシステム開発では当然のように使われているVCS（Version Control System; gitなど）と相性がとても悪いということが挙げられます。アプリケーションを構成する情報のソースがSalesforce組織内に閉じられてしまい、コードにコミットされたものと異なってしまいがちだからです。

Salesforceは、エンドユーザ自身がカスタマイズ可能な非エンジニア向けAPaaSという面と、ApexやJavaScriptコードも記述するようなコード開発者向けプラットフォームという面の両面があります。このプラットフォームの二面性は十年あまりの間に急速にユーザベースを拡大するのに貢献しましたが、一方、先述したような開発環境のモダン化という面ではお世辞にも褒められたものではありませんでした。

特に、この組織が多人数で共有されている開発用組織（Sandbox組織なども含みます）であると、ソースコードに反映されない枠外のアプリケーションメタデータが経年で肥大化しカオスになってしまいます。Sandboxの場合は定期的にリフレッシュでリセット対応できますが、頻繁にできるものではありませんし、開発中の大部分の間はアプリケーションの実体とコードの乖離を不安要素として抱え続けることになります。

別にApexとかコードレベルのカスタマイズはしないし、従来どおりVCSを使わないでアプリ開発するならいいじゃない？ という人もいるでしょう。確かにその場合アプリケーションの正となるものは常にSalesforce組織にあるのだ、といえますから、乖離はないでしょう。

ただし、それで本当に大丈夫でしょうか？　誰かジュニアエンジニアがせっかく作ったレイアウトをお試し感覚で勝手に変えたりしませんか？　それどころかオブジェクト定義自体が抹消されたりしたらどうしますか？ あと、Sandboxで作業しているときにありがちなのが、本番環境から誰かが勝手にSandboxをリフレッシュしてアプリケーション開発途中のものがパーになってしまうこと。無断で勝手に操作しやがって、とお客さんやSI担当とのコミュニケーション不備を嘆く前に、定期的にメタデータをエクスポートして自衛するのが圧倒的に安全だとは思いませんか？

結局は、コード以外の形式でSalesforceのアプリケーション設定を保存しておく術が限定的にしか存在しないのが原因です。やはりコードとしてアプリケーション設定を保持しておくこと＋VCSの導入はどんなアプリ開発にも導入は必須だといえます。

## Salesforceアプリケーション開発環境をモダン化する

それでは、以下にSalesforceアプリケーション開発をモダン化するための指針について挙げていきます。Salesforceに限らない世界ではモダンというほどモダンでもないのですが、歴史的にSaaSからプラットフォームになってきたクラウドサービスですので、最近になってやっと一般的な開発における常套手段が可能になった、という意味で「モダン」なアプローチとなります。

もちろん様々な現実があるので「おれっちの環境は全然モダンじゃないのさ…」などと卑屈にならないようにしていただきたいです。理想を知らずにただひたすら現実を呑み込むより、理想とのギャップを正しく理解して生きていくのが賢明なエンジニアの態度なのではと考えます。

### 1. 共有の開発組織を作らない

まず第１に、開発者が複数いる際に、開発時に共有する環境を作らないことです。少なくともそこで開発作業をさせないことが重要です。

共有環境はたとえ意図せずともここかしこにゴミを残し、混ぜ合わされたコードは何が原因であるかのトレースを実質的に不可能にし、再現性のない環境依存のバグを産み出します。

筆者がとある比較的大きめの開発プロジェクトに参画した際、影響の大きい変更をする際に他の開発者に邪魔されないようにタイムシェアリング・ルールを導入していたのを見たことがありますが、そのような残念な統制が行われてしまうのは、結局共有環境を利用しなければならないようになっているのがそもそもの原因なのです。

特に、テストを行う際に、環境は再現性のある状態に保てるかどうかが品質に影響します。あるときは発生していた問題がいつの間にか何もしなくても解決した（あるいはその逆）が発生してしまっているのであれば、安定的な製品・システム開発など程遠いでしょう。そのために共有環境を用いるのはできるだけ避けていくべきです。

### 2. メタデータもデータもすべてコードとして管理する

共有組織が開発・テストにとって問題であることは先に述べました。しかし、組織内には開発したプログラムコードだけでなく、オブジェクトスキーマやレイアウト、各種メタデータが依然として存在しています。これらを別々の組織で再現する必要がある場合、今まではSandboxによる組織コピーが手っ取り早く用いられていました。ただし、Sandbox組織作成は比較的高価な作業であり、頻繁に行うものではないと位置づけられていたかと思います。

もちろん、Sandboxを作らなくても、メタデータAPIやSalesforce CLI等を利用すれば、開発したプログラムコードやメタデータはすべてコードとして組織外にエクスポートできます。そしてScratch組織を利用すれば、安価かつ迅速かつ大量に同じ組織環境を再現できます。

しかし、最後に残るのはデータです。フルSandboxコピーの場合は組織内のデータも一緒にコピーしてくれましたが、Scratch組織の場合はそうはいきません。Sandboxを使わない場合のデータの移入や移出となると、いままではデータローダーで手作業、あるいはスクリプトを手組みする必要がありましたが、このような面倒なことをするくらいなら組織をポータブルにしなくてもいいか、とモチベーションが湧かなかったかもしれません。

ここで紹介したいツールとして Salesforce CLIのプラグインの [sfdx-migration-automatic](https://qiita.com/stomita/items/8d4afe92402ed66a4f97) というものがあります。現在の組織内の指定のオブジェクトのレコードをエクスポートし、新しい組織に**レコード間の関連をすべて保ったまま**インポートできるものです。レコードデータはCSVファイルとして吐き出されるため、ローカル環境で自由にExcelなどで編集することもできます。

このようにデータそのものについてもローカル環境にエクスポートできるとなると、プログラムコードやメタデータのみならずレコードデータもVCSにコミットしておき、組織の**任意の時点のコード＋データの状態をスナップショットとして保持**しておくことが可能です。つまり、**完全に同一の環境を全く別の組織にいつでも再現ができる**ようになります。

### 3. Scratch組織を使い捨てる

メタデータもデータもすべてコードで管理することで、いつでも組織再現ができるようになったなら、組織は別に後生大事にとっておかなければならないものでもありません。いつでも捨てていいはずのものです。なんなら、コミット毎にまったく違う組織を使うくらいの気持ちでもいいはずです。組織については使い捨てを前提とし、組織内でアプリケーションの状態変更を行なったらすぐにその状態を再現できるようにスナップショットしVCSにコミットすることで、いつでも状態を完全再現できます。

ただし、そのような使い捨てを前提とした組織の運用を考えた時、残念ながら問題がでてきます。Scratch組織には、日毎の作成数に制限があり、その数はあまり多くはない（Enterprise Edition契約で80組織/日、無償のDeveloper Editionだと5組織/日）のです。Enterprise Editionの上限数も複数人開発を考えたときには心もとないですし、Developer Editionの上限数はさすがに厳しいものがあります。

あまり大きな声では紹介できないのですが、[sfdx-devhub-pool](https://qiita.com/stomita/items/155092d33effe02eb4b9) というSalesforce CLIのプラグインによって、この制限内でうまく運用を回すことができます。これによりScratch組織は本来の目的として使い捨ての用途に足るようになります。

### 4. CIの導入と”Review Orgs"の可能性

このような使い捨てのScratch組織は、SalesforceにCI（継続インテグレーション）を導入するための非常に大きな一歩となります。現状ほとんどのSalesforceシステム開発ではCIを利用していないと思いますが、CIを導入している意識の高い開発チームであっても、Scratch組織登場以前ではあまり効果的にインテグレーションできていなかったかもしれません。

CIに重要なのは環境依存を排除し再現性を持ったテストが実行できるようにすることなのですが、実行毎に同じSalesforce組織を使いまわしてしまっていれば必然的に信頼性が下がってしまいます。

ここで、Scratch組織が使い捨てで利用できることを利用して、コミットごとに組織を払い出してCIによるテスト実行＋組織へのデプロイを行えば、完全に環境依存を排除できCIによるテストの信頼性は向上します（実際にはコミットごとはやりすぎでブランチくらいがちょうど良さそうですが）。

さらにこれをもっと突き進めていけば、[Heroku の Review Apps](https://devcenter.heroku.com/articles/github-integration-review-apps) 機能と同等のものがSalesforceの開発でも実現できるのです。Review Appsについて簡単に説明しておくと、GithubにPullRequestを送ると、そのPullRequestに対応したアプリが自動的にHeroku上に作成され、アクセスできるようにしてくれる機能です。これにより、レビューアは実際にアプリの動きを見てレビューを行いながらPullRequestにコメント/マージ/却下の判断を行えるというものです。PullRequest毎にまったく個別の環境ができあがるので、本番環境や他の開発者への影響を考えることなく気軽に動作を確認できるのもポイントです。

Salesforceの開発の場合でも同じように、Scratch組織をPullRequest毎に作成しデプロイを行い、組織へのログインURLを共有することで、レビューアに実際にSalesforce組織にアクセスして動きを確かめてもらうということが可能になります。Review Appsならぬ"Review Orgs"といえるでしょうか。

実際に弊社でも試験的にこのような"Review Orgs"の仕組みを取り入れて、製品の機能実装毎に個別にSalesforce組織にデプロイし、確認を行えるようにしています。CircleCIにGitHubのPRコメントを投稿するようなスクリプトを仕込んであるので、PullRequestを送りつけてしばらくするとデプロイされた組織へのログインURLがポストされてくる、という形になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6495/6e927113-85bc-d13e-33f7-edfaf80db93c.png)

## まとめ


- 組織内メタデータを正とするのではなく、VCSにコミットしているソースコードが正である開発文化に移行しよう
- Sandboxは高価かつ低頻度での作成しかできない、Scratch組織使って開発し、使い捨てよう。
- 使い捨て組織が実現できたなら、CI使うの検討しよう、メリットあるよ。
- いろいろモダンDXの導入に障害となっているものはあるが、取り除くためのツールは用意してきているよ