外部システムからApexクラスをREST APIで呼ぶ方法
Apexクラスに@RestResourceを付けて公開し、外部クライアントアプリの認証を通してREST APIとして呼び出す手順を説明します。
なぜApexを自前のREST APIにするのか
標準のREST APIは取引先や商談など、標準・カスタムオブジェクトをそのまま公開します。複数のオブジェクトをまとめて返す、独自の計算をはさむ、といった処理は標準APIだけでは足りません。そういうときは、Apexクラス自体をREST APIとして公開します。
Apexクラスを公開する書き方
クラスに @RestResource を付け、global 修飾子で宣言します。urlMapping はスラッシュで始まる相対パスで、末尾に /* を置くとワイルドカードとして後続のパスを受け取れます。
@RestResource(urlMapping='/Account/*') global with sharing class AccountRestResource { @HttpGet global static Account doGet() { RestRequest req = RestContext.request; String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/') + 1); return [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId]; } @HttpPost global static String doPost(String name, String phone, String website) { Account account = new Account(Name = name, Phone = phone, Website = website); insert account; return account.Id; } @HttpDelete global static void doDelete() { RestRequest req = RestContext.request; String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/') + 1); delete new Account(Id = accountId); } }
取引先を1件返す・作成する・削除するREST APIです。with sharingを付けているので、共有ルールが適用されます。
@HttpPost のメソッドは、引数名がそのままリクエストボディのJSONキーと対応づき、Salesforce側が自動で割り当てます。@HttpGet と @HttpDelete のメソッドは引数を持てません。IDはURLから自分で取り出します。
公開されるエンドポイント
Apex RESTのエンドポイントは、標準REST APIと違ってバージョン番号を含みません。urlMapping をそのまま続けた形になります。
https://xxxx.my.salesforce.com/services/apexrest/Account/{取引先ID}Apex RESTのエンドポイントの形です。/services/data/のようなバージョン番号は付きません。
認証の組み方
呼び出す側は、標準REST APIと同じ入口を使います。外部クライアントアプリでOAuth設定を有効化し、クライアントクレデンシャルフローかJWTベアラーフローでアクセストークンを取得します。取得したトークンを Authorization: Bearer に付けてApex RESTのURLを叩けば、通常のREST APIと同じように呼び出せます。ユーザ名パスワードフローは既定でブロックされているため使いません。
動作確認の手順
取引先を1件作る
取得・削除を試す対象として、取引先を1件作っておきます。
POSTで作成を試す
アクセストークンを付けて、名前・電話番号・URLを送り、返ってきたIDを控えます。
GETで取得を試す
控えたIDをURLの末尾に付けてGETし、登録した内容がそのまま返ることを確かめます。
curl -X POST "https://xxxx.my.salesforce.com/services/apexrest/Account/" \ -H "Authorization: Bearer xxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"name":"REST API接続テスト用","phone":"0312345678","website":"https://example.com"}'
取引先を作成してからIDで取得します。Authorizationヘッダーにアクセストークンを付けます。
ここで間違えやすい
| 間違い | 何が起きるか |
|---|---|
クラスを global にし忘れる | 外部から見えず、REST APIとして呼べません |
@HttpGet のメソッドに引数を書く | コンパイルが通りません。引数はURLから読み取ります |
| 同じHTTPメソッドのアノテーションを2つ付ける | コンパイルが通りません。クラスまたはパスを分けます |
| 権限のないユーザで呼び出す | Apexは既定でシステムモードで動くため、with sharingで効くのは共有ルールだけです。オブジェクト権限・項目レベルセキュリティも効かせたいときは、SOQLやDMLをユーザモード(WITH USER_MODEなど)で実行します |
確認した環境
- 2026年9月/Salesforce Summer '26(APIバージョン67.0)時点の公式ドキュメントで、RestResourceアノテーションとApex RESTメソッドの制約を確認しています
まとめ
- Apexクラスに
@RestResourceを付けglobalで宣言すると、REST APIとして公開できます @HttpGet・@HttpDeleteは引数を持てません。IDはURLから取り出します@HttpPostの引数名は、リクエストボディのJSONキーとそのまま対応します- エンドポイントは
/services/apexrest/から始まり、標準REST APIと違いバージョン番号を含みません - 認証は標準REST APIと同じ外部クライアントアプリの入口を使います。ユーザ名パスワードフローは使いません
参考:当時の画面
記事を最初に書いた当時の画面です。いまの手順と違うところは、各画像の説明に書いています。
Salesforceの導入・運用についてご相談ください
導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。