はじめに
こんにちは。前回の記事でSalesforceの入門資格について整理してみた、DevKumaです。
これまでアドミニストレーターやPlatform アプリケーションビルダーの学習を通して、宣言的開発(クリック操作による開発) や フロー(Flow) について勉強してきました。そんな中で、「フローでは実現が難しい処理をどうすればいいんだろう?」と思ったときに登場したのが Apex でした。
この記事は、私自身が「Apexとは何か?」を学んだ際の整理ノートとして、その全体像と「最初の一歩」をまとめてみたいと思います。
1. Apexとは何か?
まず「Apexとは何か?」ですが、これはSalesforceプラットフォーム上で動作するために作られた、独自のプログラミング言語です。
文法の特徴(JAVA経験者の方へ)
Apexの文法は Javaに非常によく似ています。静的型付け・オブジェクト指向といった特徴を持ち、たとえば String myName = 'Kuma'; や if (age > 40) { ... } といった書き方もそのまま使えます。
そのため、Javaの経験がある方であれば、文法のキャッチアップは非常にスムーズ に進むはずです。(私自身もJavaでの開発経験があったため、比較的早く慣れることができました。)
Salesforceにおける位置づけ
Salesforceは「マルチテナント」アーキテクチャ(一つのビルに複数の会社が同居しているイメージ)で動いています。そのため、特定の誰かがリソース(CPUやメモリ)を使いすぎないよう、厳しいルール(ガバナ制限)が設けられています。Apexは、そのルールの上で安全に動くように設計された専用言語、というわけですね。
2. なぜApexが必要なの?(フロー vs Apex)
これは私にとって最初の大きな疑問でした。Salesforceにはフロー (Flow)という、クリック操作で本当に高度な自動化を実現できる素晴らしい機能があります。「レコードが更新されたら、別のレコードも更新する」といった処理の多くは、フローで実現可能です。なのになぜ、わざわざコード(Apex)を書く必要があるのでしょうか?
でも、まずはフローで実現しよう
これを伝える前にまずはフローで可能であれば、フローがいいです。私も最初は「エンジニアならコード書きたいし...」と思ったりもしたのですが、これには非常に合理的で重要な理由があることが分かってきました。私なりに整理した理由は、大きく2つあります。
-
保守性(メンテナンスの容易さ)
- フローは視覚的(ビジュアル)です。
自分以外の管理者や、未来の自分が設定を見返した時、「何をやっているか」のロジックがコードよりも格段に理解しやすいです。 - Apexコードは「ブラックボックス」になりがちです。
特に非開発者にとっては、コードは読めません。書いた人が異動・退職してしまうと、誰も修正できなくなる...というリスク(=属人化)が常に伴います。
- フローは視覚的(ビジュアル)です。
-
プラットフォームのアップデート(自動的な進化)
- Salesforceは年3回(Spring, Summer, Winter)メジャーアップデートされます。
フローなどの「標準機能」は、そのアップデートのたびにSalesforceによって自動でメンテナンスされ、新機能が追加・強化されていきます。つまり、勝手に賢くなってくれるのです。 - しかし、私たちが書いたApexコードは、当然ながらSalesforceが面倒を見てくれません。
機能が古くなっても、それは「自分たちの資産(=将来の負債とも言える)」として、自分たちで未来永劫、保守し続ける必要があります。
- Salesforceは年3回(Spring, Summer, Winter)メジャーアップデートされます。
つまり、フローで可能であれば、フローで実現するのが良い理由は、将来にわたって保守しやすく、Salesforceの進化の恩恵を最大限に受けるためです。
フローではできないこと、Apexでできること
じゃあ、Apexは書かない方がいいのか?というと、全くそんなことはありません。
Apexは、このフローや標準機能の限界を超え、標準機能ではどうしても実現できない要求に応えるための、"最後の切り札"であり、強力な武器なのです。では、その「限界」とは具体的に何でしょうか?
-
例1:非常に複雑なビジネスロジック
- フローでは表現しきれない(あるいは、フローで組むと巨大すぎて逆に読めなくなる)ような、多数の条件分岐や複雑な計算、ネストしたループ処理。
-
例2:大量データの一括処理(バッチ処理)
- 「夜間に、全顧客(数万〜数百万件)のデータを一括で更新・集計する」といった、ガバナ制限(後述します)を考慮した大量データ処理。(バッチApex)
-
例3:外部システムとの高度な連携
- フローでも簡単な呼び出しは可能になりましたが、「外部のWebAPIを呼び出し、受け取ったJSONを複雑に解析して、複数のオブジェクトに書き込む」といった高度な連携(コールアウト)。
-
例4.:LWC (Lightning Web Components) のバックエンド
- 独自開発のカスタム画面(LWC)の裏側で、サーバー側の複雑なデータ操作を担う。
-
例5:厳密なエラーハンドリングとトランザクション制御
- 「処理Aと処理Bが両方成功した場合のみ全件保存し、片方でも失敗したら全部巻き戻す(ロールバックする)」といった、厳密なトランザクション管理。
このように、フローの「かゆいところに手が届かない」部分や、パフォーマンスが要求される部分を補うために、Apexは絶対に不可欠な技術となっています。
3. Apexを学ぶ前の「準備」
Apexを学ぶ前に、必須となる知識と環境があります。
-
必須の知識:管理者の知識
- ApexはSalesforceの「データ」を操作するための言語のため、基本概念である「オブジェクト」「項目」「リレーション」「データ型」の理解は必須です。(前回の記事で触れた、アドミニストレーターの範囲ですね)
-
必須の環境:Developer Edition (開発組織)
- Trailheadなどで使っている、あの無料の開発・学習環境があればOKです。
4. Apexの「Hello, World!」〜どうやって動かすの?〜
書いたApexコードはどこで実行するのでしょうか?
まずは「開発者コンソール (Developer Console)」を使います。
- Salesforce画面右上の歯車マーク ⚙ をクリック
- 「開発者コンソール」をクリック
最初の一歩:「匿名実行 (Anonymous Execution)」
開発者コンソールには、書いたコードをその場ですぐに実行できる「匿名実行」という機能があります。(学習用の"お試し実行"と捉えてください)
- 開発者コンソールのメニューで
Debug>Open Execute Anonymous Windowを開きます。 - 以下のコードを貼り付けて
Executeをクリックします。
// Javaの「System.out.println」や JavaScriptの「console.log」と同じ
// 「ログ(実行記録)」にメッセージを出力します。
System.debug('Hello, Apex!');
-
Executeを押した後、下部のLogsタブにログ(実行記録)が表示されます。 - ログをダブルクリックで開き、
Debug Onlyにチェックを入れると、Hello, Apex!と表示されているのが確認できるはずです。
これが、Apexの「Hello, World!」です。
5. Apexの超基本文法
Apexの基本的な文法は、Javaとほぼ同じです。(ここでは詳細な文法は割愛しますが、変数、IF文、forループなどは同じように使えます)
// 変数
String myName = 'Kuma'; // 文字列
Integer myAge = 40; // 整数
// リスト (List)
List<String> fruits = new List<String>{'Apple', 'Orange', 'Banana'};
System.debug(fruits[0]); // 結果: Apple
// IF文 (条件分岐)
if (myAge >= 40) {
System.debug('成人です');
}
6. Salesforce特有のApex 〜最重要〜
ここからがApexの本番であり、私が最初につまずいたポイントです。
Salesforceの「データ」を操作するための、最も重要な仕組みを3つ紹介します。
① SObject
SObjectとは、Salesforceの「レコード」を扱うための特別なデータ型(オブジェクト型)です。
Account(取引先)レコード、Contact(取引先責任者)レコード、MyCustomObject__c レコードなど、Salesforce上の1件のデータは、Apex上ではすべてSObjectとして扱います。
// 1. 空の「取引先」レコードをメモリ上に作成
Account acc = new Account();
// 2. 項目(フィールド)に値を設定
acc.Name = '株式会社クマガイ';
acc.Phone = '01-2345-6789';
acc.CustomField__c = 'カスタム項目の値'; // カスタム項目は __c が付く
// 3. データベースに「挿入 (Insert)」する
insert acc;
// 挿入が成功すると、acc.Id に自動でIdが採番される
System.debug(acc.Id);
insert (挿入), update (更新), delete (削除) といった命令を DML (Data Manipulation Language) と呼びます。
② SOQL (ソークィル)
SOQL (Salesforce Object Query Language) とは、Salesforceのデータベースからデータを「取得 (SELECT)」するためのクエリ言語です。みなさんご存知の SQL (Structured Query Language) に非常によく似ています。
/*
* [ ] (角括弧) で囲むのが特徴です。
* SELECT [取得したい項目]
* FROM [取得したいオブジェクト]
* WHERE [絞り込み条件]
*/
// 「株式会社サンプル」という名前の取引先 (Account) の Name と Phone を取得する
Account acc = [SELECT Name, Phone
FROM Account
WHERE Name = '株式会社サンプル'
LIMIT 1];
System.debug(acc.Phone); // 結果: 03-1234-5678
③ ガバナ制限 (Governor Limits)
これ、本当に重要です。Apexを学ぶ上で、絶対に避けて通れない最重要ルールです。
「2. Apexとは何か?」で触れた通り、Salesforceは「相乗り」環境です。1回の処理で使えるリソース(CPU時間、DBアクセス回数など)に厳しい「制限」が設けられており、これをガバナ制限と呼びます。
例:1回の処理でSOQL(DBアクセス)は100回まで。
ガバナ制限があるため、可能なかぎりApexでは「ループの中でDMLやSOQLを発行する」ことは避けてください。
【アンチパターン】
// 1. 200件の取引先を取得 (この時点でSOQL 1回)
List<Account> accounts = [SELECT Id FROM Account LIMIT 200];
// 2. ループが200回回る
for (Account acc : accounts) {
// 3. ループの中で SOQL を発行している!
// これが 101 回目に達した瞬間に、エラーで処理が停止します。
Contact con = [SELECT Name FROM Contact WHERE AccountId = acc.Id LIMIT 1];
}
このガバナ制限を回避するために、ApexではBulkify(一括処理化)という設計手法が必須となります。(この話は長くなるので、また別の記事で整理したいと思います。参考記事だけ共有しておきます。Effective Bulk Apex Trigger Design Techniques - Trailhead )
7. Apexの主な使い道(トリガとクラス)
では、これらのApexコードは、実際にはどこに書いて、いつ動くのでしょうか?
1. Apexトリガ (Trigger)
最もよく使う機能の一つのようです。「レコードが保存(Insert, Update, Delete)された時」に自動で起動する処理を仕込むことができます。
- 例: 「商談(Opportunity)」のフェーズが「受注」になったら、自動で「取引先(Account)」の「年間売上」項目を更新する。
(※注意:最近は、レコードが作成・更新された時の処理は、まず「レコードトリガーフロー」で実現できないか検討するのが主流のようです。フローでできない複雑な場合にトリガを使いましょう。)
2. Apexクラス (Class)
ロジック(処理)をまとめたものです。LWC (画面)から呼び出されたり、バッチ処理 (Batch Apex)として夜間に動いたり、外部APIを呼び出す処理を書いたりと、Apexのロジック本体は基本的にこの「クラス」に記述します。
学習の次のステップ
-
Trailhead (トレイルヘッド)
- やはり、何はともあれTrailheadです。
- 「Apex の基礎」「Apex トリガ」「Apex テスト」といったモジュールが、ハンズオン(実習)形式で無料で学べます。参考になりそうなモジュールをまとめてみました。
-
資格
- Apexを学んだ先には「Platform デベロッパー」資格があります。
- (ただし、前回の記事でも触れたように、受験前に「アドミニストレーター」「Platform アプリケーションビルダー」の知識を固めることを強く推奨します。ガバナ制限やフローの理解が必須となるためです。)
おわりに
Apexは、Salesforceの標準機能やフローでは実現できないことを可能にする、非常に強力なものです。
ガバナ制限など独特なルールはありますが、Javaの経験があればキャッチアップは早いですし、初心者であってもTrailheadという最高の学習環境が用意されています。
まずは開発者コンソールを開いて、System.debug('Hello, Apex!'); から、第一歩を一緒に踏み出してみましょう!以上devKumaでした。