Salesforceの導入サポート、開発・連携を行う(株)FDCのエンジニアチームが、Salesforce Apex開発について基礎から活用事例まで徹底的に解説します。
「Apexって何?」「フローと何が違うの?」という疑問をお持ちの方でも読み進めやすい内容です。
Salesforceの標準機能だけでは対応しきれない複雑な業務ロジックや外部システム連携を実現するうえで、Apexは欠かせない技術です。本記事を通じて、Apexの全体像と実務への活かし方を具体的にイメージできる状態をぜひ掴んでみてください。

Salesforce Apexとは?基本概念をわかりやすく理解しよう
Apexとは、Salesforceプラットフォーム上でサーバーサイドで動作する強く型付けされたオブジェクト指向プログラミング言語です。Salesforce公式ドキュメント(Apex 開発者ガイド)では次のように定義されています。
「Apexは、開発者がSalesforceサーバーでフローとトランザクションの制御ステートメントをAPIへのコールと組み合わせて実行できるようにした、強く型付けされたオブジェクト指向のプログラミング言語です。」
(出典:Apex 開発者ガイド | Salesforce Developers)
文法はJavaに近く、データベースのストアドプロシージャーのように動作します。ボタンクリック・レコードの更新・Webサービスリクエストなど、ほぼすべてのシステムイベントにビジネスロジックを追加できる点が大きな特徴です。
Apexの主な特徴
- 統合されている:DML(INSERT/UPDATE/DELETE)、SOQL、SOSLがネイティブでサポートされ、Salesforceのデータ操作を直感的に記述できます。
- 強く型付けされている:スキーマオブジェクト(オブジェクト名・項目名)を直接参照するため、参照が無効な場合はコンパイル時にエラーが検出されます。
- マルチテナント対応:Salesforceはマルチテナント環境のため、共有リソースが独占されないようApexランタイムエンジンがガバナ制限を強制します。
- テストが容易:単体テストの作成・実行サポートが組み込まれており、本番リリース時には75%以上のコードカバレッジが必須です。
- バージョン管理:異なるAPIバージョンにコードを保存できるため、動作を安定して維持できます。
Apexが利用できるSalesforceエディション
| エディション | Apex利用可否 |
|---|---|
| Enterprise Edition | ○ |
| Performance Edition | ○ |
| Unlimited Edition | ○ |
| Developer Edition | ○ |
| Database.com Edition | ○ |
| Essentials / Professional Edition | △(制限あり/アドオンが必要な場合あり) |
Salesforce ApexとFlow(フロー)の違い:どちらを使うべきか
Salesforceで業務自動化を検討する際、まずはFlowの利用を優先することが推奨されています。Salesforce自身も「Flow First」の方針を掲げており、ノーコードで実現できる範囲はFlowで対応するのが基本です。ただし、複雑な条件分岐・大量データ処理・外部システムとの双方向連携が必要になった段階で、Apexの出番になります。
| 比較観点 | Flow(フロー) | Apex |
|---|---|---|
| 開発スピード | ◎ 画面操作で視覚的に構築でき、短期間で実装可能 | △ コード記述+テストクラス作成が必須で工数がかかる |
| 学習難易度 | ◎ プログラミング未経験者でも学びやすい | △ プログラミングの基礎知識と特有の文法・設計思想が必要 |
| メンテナンス性 | ◎ 処理の流れが図で可視化され、非開発者でも把握しやすい | △ コードを読める開発者が必要で属人化リスクあり |
| 複雑なロジック | △ フロー図が複雑化するとメンテナンスが困難になる | ◎ コードで記述するため複雑な条件分岐・計算もスッキリ管理できる |
| 大量データ処理 | △ 数千件以上のデータ処理では速度低下リスクが高まる | ◎ 大量データを高速かつ安全に処理するための仕組みが充実 |
| 外部システム連携 | ✕ 外部から呼び出されるAPIの作成は不可 | ◎ 独自APIの公開・外部システムとの双方向連携が可能 |
判断基準をシンプルにまとめると、「シンプルな自動化はFlow、複雑・大量・外部連携が伴う処理はApex」です。実際の現場ではFlowで基本処理を組み、一部の複雑なロジックだけをApexのInvocable Actionとして呼び出す「ハイブリッド構成」も広く使われています。
Apex開発の主要コンポーネント
Apexクラス
Apexクラスは、関連する処理(メソッド)をまとめたコードの集合体です。クラスの中には複数のメソッドを定義でき、各メソッドが具体的な処理(例:「売上計算」「メール送信」)を担います。Javaのクラス定義に近い構文で、アクセス修飾子(public / private / global)を指定して定義します。
Apexトリガー
Apexトリガーは、Salesforceレコードへの変更の前後にカスタムアクションを実行する仕組みです。トリガーには2種類あり、用途に応じて使い分けます。
- before トリガー:レコードがデータベースに保存される前に実行。値の検証や上書きに使用します。追加のDMLなしでレコードの値を変更できるため、処理効率の面でも優れています。
- after トリガー:レコードが保存された後に実行。他レコードの更新・外部システムへの通知などに使用します。このタイミングではレコードにIDが採番されているため、関連レコードの作成にも適しています。
テストクラス
Apexコードを本番環境にデプロイするには、テストクラスによるコードカバレッジが75%以上必要です。テストクラスは@isTestアノテーションを付けて定義します。テストデータは@TestSetupメソッドで一括生成し、各テストメソッドでSystem.assert()を使って期待値を検証するのが基本パターンです。
ガバナ制限(Governor Limits)とは?Salesforce Apex開発で必須の知識
Salesforceのマルチテナント環境では「ガバナ制限」が設けられており、これを超えると実行時例外(System.LimitException)が発生してトランザクション全体がロールバックされます。Apex開発者にとって、この制限を理解し回避する設計ができるかどうかは実力を測る指標の一つといえます。
| 制限の種類 | 同期Apex | 非同期Apex |
|---|---|---|
| SOQLクエリの合計数 | 100回 | 200回 |
| SOQLクエリで取得できるレコード総数 | 50,000件 | 50,000件 |
| DMLステートメントの合計数 | 150回 | 150回 |
| DMLで処理できるレコード総数 | 10,000件 | 10,000件 |
| コールアウトの合計数 | 100回 | 100回 |
| 最大CPU時間 | 10,000ms | 60,000ms |
| ヒープサイズ | 6 MB | 12 MB |
| 最大トランザクション実行時間 | 10分 | 10分 |
特に開発初期に陥りやすいのが、SOQLクエリの100回制限とDMLステートメントの150回制限です。後述する「バルク化」を徹底することで、これらの制限に抵触するリスクを大幅に減らせます。
非同期Apex:大量データ処理を実現する4つの手法
同期Apexのガバナ制限では処理しきれない大量データや、長時間かかる外部連携処理には、非同期Apexを使います。Salesforceには目的に応じた4つの非同期処理手法が用意されています。
Batch Apex(バッチApex)
数百万件規模のレコードをチャンク(デフォルト200件単位)に分割して順次処理します。各executeメソッドの実行ごとにガバナ制限がリセットされるため、大量データでも制限に抵触しにくい設計です。夜間の一括データ更新や月次集計処理などの定型バッチに最適です。
Futureメソッド(@future)
@futureアノテーションを付与したメソッドは、現在のトランザクションとは別にバックグラウンドで非同期実行されます。トリガー内から外部APIへコールアウトしたい場合に頻繁に使われます。ただし、ジョブの実行順序は保証されず、引数にsObjectを渡せない(プリミティブ型のみ)といった制約があります。
Queueable Apex
System.enqueueJob()でジョブをキューに追加して非同期実行します。Futureメソッドより柔軟で、sObjectやApexクラスのインスタンスを引数に渡せるほか、ジョブのチェーン(連続実行)も可能です。「Futureメソッドの上位互換」として、新規開発ではこちらが推奨されるケースが増えています。
Schedule Apex(スケジュールApex)
Schedulableインターフェースを実装することで、Cron式で指定した日時にApexを定期実行できます。Batch Apexと組み合わせて「毎日深夜2時に顧客データを一括更新する」といった定期ジョブを構築するのが代表的な使い方です。
Salesforce Apex開発のベストプラクティス
1. バルク化(Bulkification)を徹底する
ループ内でのSOQLクエリやDML操作は絶対に避けましょう。これはApex開発における最重要ルールです。レコードをListやMapに格納してからループ外で一括処理するのが鉄則です。たとえば、取引先責任者の更新トリガーで親取引先の情報が必要な場合、ループの外でまず全件分の取引先IDを収集し、1回のSOQLで取引先をMapに格納してからループ内で参照する、という手順になります。
2. トリガーハンドラーパターンを採用する
トリガーファイルには起動条件の判定と呼び出しのみを記述し、ビジネスロジックはハンドラークラスに分離するのがベストプラクティスです。1オブジェクトにつきトリガーは1つに統一し、ハンドラークラス側でbeforeInsert、afterUpdateなどイベントごとにメソッドを分けて管理すると、再利用性・テスタビリティ・可読性のすべてが向上します。
3. 例外処理(try-catch)を適切に行う
外部APIへのコールアウトやDML操作ではtry-catchブロックを活用し、エラー発生時のリカバリー処理を適切に設計してください。catchブロックでは単にエラーを握りつぶすのではなく、ログの記録やユーザーへの通知を行うことが重要です。
4. テスト駆動開発(TDD)を意識する
コードを書きながらテストクラスも同時に作成するTDDの考え方を取り入れましょう。75%以上のコードカバレッジはデプロイの最低条件ですが、実務上は90%以上を目標にすることで品質が安定します。正常系だけでなく、バリデーションエラーやNull値が入った場合の異常系テストも必ず含めてください。
5. セキュリティ(FLS・オブジェクト権限)を考慮する
Apexはデフォルトで「システムモード」(全権限)で実行されるため、ユーザーの項目レベルセキュリティ(FLS)やオブジェクト権限を意識的にチェックする必要があります。with sharingキーワードの使用でレコードレベルの共有ルールを適用できるほか、Security.stripInaccessible()メソッドでFLSを一括チェックする方法も有効です。
Salesforce Apex開発の実践活用事例
事例1:基幹システム(ERP)との受注・請求連携
製造業・卸売業で多く見られるパターンです。営業担当が商談を「クローズ済み」に更新した瞬間に、Salesforce側からERPへ自動的に受注データを連携します。
処理の流れ:
- トリガー起動:商談(Opportunity)のafterUpdateトリガーが、ステージが「Closed Won」に変わったことを検知して起動します。
- データ収集:商談に紐づく取引先情報・商品明細(OpportunityLineItem)をSOQLで一括取得します。バルク化を意識し、複数商談が同時更新された場合にも対応できる設計にします。
- ERP連携(Callout):トリガーから直接Calloutはできないため、Queueable Apexにデータを渡して非同期でERPのREST APIを呼び出します。認証にはNamedCredentialを使用し、認証情報をコードにハードコードしない設計にします。
- 結果の書き戻し:ERPから返却された受注IDをSalesforceの商談レコードに書き戻します。エラー発生時はカスタムオブジェクトにエラーログを記録し、管理者にメール通知を送ります。
このパターンのポイントは、トリガー→Queueableの非同期分離と、NamedCredentialによるセキュアな認証設計です。
事例2:カスタムRESTful APIの公開
Apexを使うことで、Salesforceを独自のAPIエンドポイントとして外部に公開できます。@RestResourceアノテーションを付与したクラスを作成し、@HttpGetや@HttpPostでHTTPメソッドに対応するメソッドを定義します。
たとえばECサイトから顧客情報をリアルタイムに参照したい場合、Salesforce側に/services/apexrest/customers/というエンドポイントを作成し、ECサイト側からHTTP GETで呼び出す構成が可能です。モバイルアプリや社内ポータルなど、複数のフロントエンドからSalesforceをデータハブとして活用するケースで威力を発揮します。
事例3:大量データのバッチ処理・定期実行
Batch ApexとSchedule Apexの組み合わせは、定期的な大量データ処理の定番パターンです。具体的な活用例としては、毎月末に全取引先の取引実績を集計して「顧客ランク」を自動更新する処理が挙げられます。
Batch ApexのstartメソッドでSOQLを使って対象レコード(数十万件の取引先)を取得し、executeメソッドで200件ずつランク計算・更新を行い、finishメソッドで処理完了メールを送信する、という3段構成です。Schedule Apexでこのバッチを「毎月最終日の深夜2時」に起動するようCron式で設定すれば、完全自動化が実現します。
事例4:複雑な承認ロジックの実装
標準の承認プロセスでは対応できない多段階・条件分岐の承認ワークフローもApexで柔軟に実装できます。たとえば「金額100万円以上は部長承認→役員承認、ただし既存顧客のリピート案件は部長承認のみ」といった条件分岐を含む承認フローは、標準機能だけでは管理が煩雑になります。Apexであれば承認ステップの条件判定ロジックをコードで明確に記述でき、将来の条件追加にも柔軟に対応できます。
2026年最新アップデート|Spring ’26リリースのSalesforce Apex新機能
① Apex Cursors が正式リリース(GA:API v66.0)
Apex CursorsがSpring ’26で正式リリースされました。従来、大規模なSOQL結果セットを分割処理するにはBatch Apexを使う必要がありましたが、Apex Cursorsを使えばQueueable ApexやLWC(Lightning Web Components)のサーバー処理内でも柔軟なページネーションが実現できます。Database.getCursorLocator()で取得したカーソルを使い、任意の位置から任意の件数だけレコードを取得できるため、UIのページ送りや段階的なデータ処理の実装が大幅に簡素化されます。
② レコードタイプ別の選択リスト値取得メソッド追加
新メソッドConnectApi.RecordUi.getPicklistValuesByRecordType()により、Apex単体でレコードタイプ別の選択リスト値をネイティブに取得できるようになりました。従来はUI APIへのCalloutやカスタムメタデータでの管理が必要だったため、動的フォームやLWCコンポーネント開発の効率が向上します。
③ Blob.toPdf() のPDFレンダリングエンジンが刷新
日本語・中国語・韓国語(CJK文字)を含む多バイト文字の表示が改善され、国際向けPDF生成の信頼性が向上しました。日本語環境で帳票PDFを生成しているユーザーにとっては大きな改善です。なお、このエンジン変更はSummer ’26で強制適用となるため、既存のBlob.toPdf()利用コードがある場合は早めの動作確認を推奨します。
④ RunRelevantTests(関連テストのみ実行)がBeta公開
変更したコードに関連するテストだけを自動選択して実行する機能がBeta公開されました。大規模な組織でのデプロイ時間の大幅な短縮が期待できます。これまで「Run All Tests」で数時間かかっていたデプロイが、変更影響範囲のテストのみに絞られることで大幅に効率化されます。
Salesforce Apex開発でお困りの方へ|SFsolutionのご紹介
ここまでSalesforce Apex開発の基礎から活用事例、最新機能までを解説してきました。記事を読んで「自社でも外部連携やバッチ処理を実装したいが、社内にApex開発ができるエンジニアがいない」「既存のApexコードの保守が属人化していて不安」と感じた方もいらっしゃるのではないでしょうか。
そんな方におすすめなのが、弊社(株)エフ・ディー・シーが提供しているSalesforce導入・活用サポートサービス「SFsolution」です。ERP連携やカスタムAPI開発など、今回ご紹介した事例のような開発案件にも対応しています。興味をお持ちの方は、ぜひお問い合わせまたは資料ダウンロードからお気軽にご連絡ください。
