Apex Web サービス
学習の目的
- 2 種類の Apex Web サービスとこれらのサービスの概要について説明する。
- 各 HTTP メソッドに対応するメソッドが含まれる Apex REST クラスを作成する。
- エンドポイントを使用してカスタム Apex REST メソッドを呼び出す。
- JSON 形式でリクエストボディを送信し、カスタム Apex REST メソッドにデータを渡す。
- Apex REST メソッドのテストメソッドを作成して、テスト REST 要求でプロパティを設定する。
- パラメータ値でメソッドをコールして、Apex REST メソッドのテストメソッドを作成する。
Apex クラスを Web サービスとして公開
たとえば、自社のコールセンターで内部アプリケーションを使用して、社内リソースを管理しているとします。カスタマーサポート担当者は、同じアプリケーションを使用して日常業務 (Salesforce のケースレコードの管理など) も行えるようになります。担当者は、1 つのインターフェースを使用して、ケースレコードの表示や更新を行ったり、内部リソースにアクセスしたりできます。アプリケーションは、Apex Web サービスクラスをコールして、Salesforce ケースレコードを管理します。
REST サービスとしてクラスを公開
Apex クラスを REST Web サービスとして使用できるようにすることは簡単です。クラスをグローバルクラス、メソッドをグローバル静的メソッドとして定義します。アノテーションをクラスおよびメソッドに追加します。たとえば、このサンプル Apex REST クラスでは 1 つのメソッドを使用します。getRecord メソッドは、カスタム REST API コールです。これは、@HttpGet アノテーションが付加されており、GET 要求で呼び出されます。
@RestResource(urlMapping='/Account/*') global with sharing class MyRestResource { @HttpGet global static Account getRecord() { // Add your code } }
ご覧のとおり、クラスには @RestResource(urlMapping='/Account/*') アノテーションが付加されています。Apex REST のベースエンドポイントは、https://yourInstance.salesforce.com/services/apexrest/ です。URL 対応付けがベースエンドポイントに追加されて、REST サービスのエンドポイントが形成されます。たとえば、このクラスの例の REST エンドポイントは https://yourInstance.salesforce.com/services/apexrest/ です。お客様の組織では、https://yourInstance.salesforce.com/services/apexrest/Account/* のようになります。
URL 対応付けでは大文字と小文字が区別され、ワイルドカード (*) を含めることができます。
global static として公開する各メソッドを定義し、HTTP メソッドと関連付けるアノテーションを追加します。次のアノテーションを使用できます。それぞれのアノテーションは、各 Apex クラスで 1 回のみ使用できます。
アノテーション | アクション | 詳細 |
---|---|---|
@HttpGet | 参照 | レコードを参照または取得します。 |
@HttpPost | 作成 | レコードを作成します。 |
@HttpDelete | 削除 | レコードを削除します。 |
@HttpPut | 更新/挿入 | 通常、既存のレコードを更新したり、レコードを作成したりするために使用します。 |
@HttpPatch | 更新 | 通常、既存のレコードの項目を更新するために使用します。 |
SOAP サービスとしてクラスを公開
Apex クラスを SOAP Web サービスとして使用できるようにすることは REST と同様に簡単です。クラスをグローバルクラスとして定義します。公開する各メソッドに webservice キーワードと static 定義修飾子を追加します。webservice キーワードを追加したメソッドにはグローバルアクセス権が付与されます。
たとえば、次に 1 つのメソッドがあるサンプルクラスを示します。getRecord メソッドは、取引先レコードを返すカスタム SOAP API コールです。
global with sharing class MySOAPWebService { webservice static Account getRecord(String id) { // Add your code } }
外部アプリケーションは、クラス WSDL ファイルを使用して、カスタム Apex メソッドを Web サービス処理としてコールできます。[設定] の [Apex クラス] ページからアクセスするクラスの詳細ページで、クラスのこの WSDL を生成します。通常、WSDL ファイルをサードパーティ開発者に送信 (または自身で使用) して、Web サービスのインテグレーションを作成します。
プラットフォームセキュリティは、Salesforce の最重要事項であるため、Web サービスから認証が要求されます。外部アプリケーションは、Apex クラスの WSDL の他に Enterprise WSDL または Partner WSDL を使用してログイン機能を実現する必要があります。
Apex REST のウォークスルー
Apex クラスは、ケースレコードを管理します。クラスには 5 個のメソッドがあり、各メソッドは HTTP メソッドに対応します。たとえば、クライアントアプリケーションが GET HTTP メソッドの REST コールを呼び出す場合、getCaseById メソッドが呼び出されます。
クラスは /Cases/* の URL 対応付けで定義されているので、この REST サービスをコールするために使用されるエンドポイントは、https://yourInstance.salesforce.com/services/apexrest/Cases/ で始まる URI になります。
既存のコードを壊すことなく機能をアップグレードできるように、API エンドポイントのバージョン管理についても検討することをお勧めします。/Cases/v1/* と /Cases/v2/* の URL 対応付けを指定する 2 つのクラスを作成して、この機能を実装できます。
では、Apex REST クラスの作成から始めましょう。
- 設定ギア (
) から開発者コンソールを開きます。
- 開発者コンソールで、 を選択します。
- クラス名として「CaseManager」と入力し、[OK] をクリックします。
- 自動生成されるコードを次のクラス定義で置き換えます。
@RestResource(urlMapping='/Cases/*') global with sharing class CaseManager { @HttpGet global static Case getCaseById() { RestRequest request = RestContext.request; // grab the caseId from the end of the URL String caseId = request.requestURI.substring( request.requestURI.lastIndexOf('/')+1); Case result = [SELECT CaseNumber,Subject,Status,Origin,Priority FROM Case WHERE Id = :caseId]; return result; } @HttpPost global static ID createCase(String subject, String status, String origin, String priority) { Case thisCase = new Case( Subject=subject, Status=status, Origin=origin, Priority=priority); insert thisCase; return thisCase.Id; } @HttpDelete global static void deleteCase() { RestRequest request = RestContext.request; String caseId = request.requestURI.substring( request.requestURI.lastIndexOf('/')+1); Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId]; delete thisCase; } @HttpPut global static ID upsertCase(String subject, String status, String origin, String priority, String id) { Case thisCase = new Case( Id=id, Subject=subject, Status=status, Origin=origin, Priority=priority); // Match case by Id, if present. // Otherwise, create new case. upsert thisCase; // Return the case ID. return thisCase.Id; } @HttpPatch global static ID updateCaseFields() { RestRequest request = RestContext.request; String caseId = request.requestURI.substring( request.requestURI.lastIndexOf('/')+1); Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId]; // Deserialize the JSON string into name-value pairs Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring()); // Iterate through each parameter field and value for(String fieldName : params.keySet()) { // Set the field and value on the Case sObject thisCase.put(fieldName, params.get(fieldName)); } update thisCase; return thisCase.Id; } }
- CTRL+S キーを押して保存します。
POST メソッドを使用したレコードの作成
REST サービスを呼び出すには、REST クライアントを使用する必要があります。独自の API クライアント、cURL コマンドラインツール、PHP の cURL ライブラリなど、ほぼすべての REST クライアントを使用できます。REST クライアントアプリケーションとしてワークベンチツールを使用しますが、後で cURL についても少し触れます。
Apex REST は、リソースを表現するために、JSON と XML の 2 つの形式をサポートしています。JSON による表現は、要求またはレスポンスボディにデフォルトで渡され、形式は、HTTP ヘッダーの Content-Type プロパティで示されます。XML よりも JSON の方が読みやすく理解しやすいので、この単元では JSON のみを使用します。このステップでは、JSON 形式でケースレコードを送信します。
Apex REST では、OAuth 2.0 とセッション認証メカニズムがサポートされています。簡単に言えば、これは業界標準を使用して、アプリケーションとデータを安全に保持するということです。幸いにも、ワークベンチを使用して簡単にテストを実行できます。ワークベンチは、システム管理者および開発者が Lightning Platform API を使用して組織とやりとりするための強力な Web ベースのツールです。ワークベンチでは、ユーザ名とパスワードで Salesforce にログインするときにセッション認証を使用します。次に、REST Explorer を使用して REST サービスをコールします。
- https://workbench.developerforce.com/login.php に移動します。
- [Environment (環境)] で [Production (本番)] を選択します。
- [API Version (API バージョン)] ドロップダウンから最新の API バージョンを選択します。
- サービスの利用規約に同意し、[Salesforce でログイン] をクリックします。
- ワークベンチが自分の情報にアクセスできるようにするには、[Allow (許可)] をクリックします。
- ログイン情報を入力し、[Log in to Salesforce (Salesforce へのログイン)] をクリックします。
- ログインしたら、 を選択します。
- [POST] を選択します。
- REST Explorer では、組織のインスタンス URL に対する相対パスを指定する必要があるため、インスタンス URL に追加するパスのみを入力します。相対 URI の入力項目で、デフォルトの URL を /services/apexrest/Cases/ で置き換えます。
-
リクエストボディに、挿入するオブジェクトを示す次の JSON 文字列を挿入します。
{ "subject" : "Bigfoot Sighting!", "status" : "New", "origin" : "Phone", "priority" : "Low" }
-
[実行] をクリックします。この呼び出しでは、POST HTTP メソッドに関連付けられたメソッド (createCase メソッド) をコールします。
-
返された応答を表示するには、[Show Raw Response (未加工の応答を表示)] をクリックします。返された応答は、次のようになります。応答には、新しいケースレコードの ID が含まれます。あなたの ID 値は 50061000000t7kYAAQ とは違う可能性があります。次のステップで使用するために ID 値を保存します。
HTTP/1.1 200 OK Date: Wed, 07 Oct 2015 14:18:20 GMT Set-Cookie: BrowserId=F1wxIhHPQHCXp6wrvqToXA;Path=/;Domain=.salesforce.com;Expires=Sun, 06-Dec-2015 14:18:20 GMT Expires: Thu, 01 Jan 1970 00:00:00 GMT Content-Type: application/json;charset=UTF-8 Content-Encoding: gzip Transfer-Encoding: chunked "50061000000t7kYAAQ"
カスタム GET メソッドを使用したデータの取得
前回と同様の手順に従い、ワークベンチを使用して GET HTTP メソッドを呼び出します。
- ワークベンチで、[GET] を選択します。
- URI /services/apexrest/Cases/<Record ID> を入力します。<Record ID> は、前のステップで作成したレコードの ID に置き換えます。
-
[実行] をクリックします。
この呼び出しでは、GET HTTP メソッドに関連付けられたメソッド (getCaseById メソッド) をコールします。
-
返された応答を表示するには、[Show Raw Response (未加工の応答を表示)] をクリックします。
返された応答は、次のようになります。応答には、メソッドが新しいケースレコードを照会した項目が含まれます。
HTTP/1.1 200 OK Date: Wed, 07 Oct 2015 14:28:20 GMT Set-Cookie: BrowserId=j5qAnPDdRxSu8eHGqaRVLQ;Path=/;Domain=.salesforce.com;Expires=Sun, 06-Dec-2015 14:28:20 GMT Expires: Thu, 01 Jan 1970 00:00:00 GMT Content-Type: application/json;charset=UTF-8 Content-Encoding: gzip Transfer-Encoding: chunked { "attributes" : { "type" : "Case", "url" : "/services/data/v34.0/sobjects/Case/50061000000t7kYAAQ" }, "CaseNumber" : "00001026", "Subject" : "Bigfoot Sighting!", "Status" : "New", "Origin" : "Phone", "Priority" : "Low", "Id" : "50061000000t7kYAAQ" }
cURL を使用したデータの取得
優れた開発者なら誰でも、1) アイスクリームを食べる自分のアニメーション GIF を作成する方法、2) 円周率 25 桁までの値、3) cURL の使用方法くらいは知っています。最初の 2 つはこのモジュールでは取り上げませんので、最後の 1 つに焦点を絞りましょう。
cURL は、URL 構文を使用してファイルを取得または送信するためのコマンドラインツールです。このツールは、REST エンドポイントを使用して作業するときに非常に役に立ちます。Apex REST サービスのワークベンチを使用する代わりに、cURL を使用して GET HTTP メソッドを呼び出します。REST エンドポイントを「cURL」するたびに、認証用のセッション ID を渡します。ワークベンチで作業する場合は、ログインすると内部的にセッション ID が渡されます。
セッション ID を取得するには、まず Salesforce 組織で接続アプリケーションを作成し、OAuth を有効にします。クライアントアプリケーション (この場合は cURL) は、接続アプリケーションを使用して Salesforce に接続します。こちらの手順に従って、セッション ID を取得するために必要なコンシューマ鍵とコンシューマの秘密を提供する接続アプリケーションを作成します。接続アプリケーションの OAuth 範囲を選択するときは、「データへのアクセスと管理 (api)」範囲を選択します。接続アプリケーションによる設定が完了するまで 5 ~ 10 分かかる場合があります。準備ができたら、自分のログイン情報と接続アプリケーションを使用して次の cURL コマンドを実行します。
任意のコマンドラインツール (macOS/Linux のターミナル、Windows のコマンドプロンプトなど) を使用して、これらの要求を実行します。
curl -v https://login.salesforce.com/services/oauth2/token -d "grant_type=password" -d "client_id=<your_consumer_key>" -d "client_secret=<your_consumer_secret>" -d "username=<your_username>" -d "password=<your_password_and_security_token>" -H 'X-PrettyPrint:1'
すべて成功すると、結果にはセッション ID である access_token と組織の instance_url が含まれます。
続いて、次のような cURL コマンドを入力します。このコマンドは Apex REST サービスをコールし、ケース情報を返します。
curl https://yourInstance.salesforce.com/services/apexrest/Cases/<Record_ID> -H 'Authorization: Bearer <your_session_id>' -H "X-PrettyPrint:1"
Enter キーを押すと、次のような画面が表示されます。これでコマンドラインを習得できたので、cURL、jq、sed、awk、grep を思う存分遠慮なくご使用ください。cURL についての詳細は、「リソース」セクションを参照してください。

カスタム PUT または PATCH メソッドを使用したデータの更新
PUT メソッドを使用したデータの更新
CaseManager クラスに追加した upsertCase メソッドは、PUT アクションを実装します。ここに記載されているこのメソッドは参照用です。このメソッドは組み込みの upsert Apex DML メソッドを使用し、ID 値を照合してケースレコード項目を作成または上書きします。ID がリクエストボディで送信された場合、その ID を使用してケースの sObject が入力されます。ID が送信されない場合は、ID を使用せずにケースの sObject が作成されます。入力されるケースの sObject で upsert メソッドが呼び出され、DML ステートメントで残りの作業が行われます。成功です。
@HttpPut global static ID upsertCase(String subject, String status, String origin, String priority, String id) { Case thisCase = new Case( Id=id, Subject=subject, Status=status, Origin=origin, Priority=priority); // Match case by Id, if present. // Otherwise, create new case. upsert thisCase; // Return the case ID. return thisCase.Id; }
- ワークベンチ REST Explorer で、[PUT] を選択します。
- URI として「/services/apexrest/Cases/」と入力します。
-
upsertCase メソッドでは、項目値がリクエストボディで渡されます。リクエストボディに次の内容を追加して、<Record ID> を前に作成したケースレコードの ID に置き換えます。
{ "id": "<Record_ID>", "status" : "Working", "subject" : "Bigfoot Sighting!", "priority" : "Medium" }
-
[実行] をクリックします。
この要求は、REST サービスから upsertCase メソッドを呼び出します。[状況]、[件名]、[優先度] 項目が更新されます。件名は、古い値と同じでも更新されます。また、リクエストボディには、[発生源] 項目の値が含まれていないため、upsertCase メソッドの origin パラメータは null になります。その結果、レコードが更新されると、[発生源] 項目がクリアされます。
これらの項目を確認するには、https://yourInstance.salesforce.com/<Record ID> に移動して Salesforce のこのレコードを表示します。
PATCH メソッドを使用したデータの更新
PUT メソッドの代わりに PATCH メソッド使用してレコード項目を更新できます。PATCH メソッドはさまざまな方法で実装できます。その方法の 1 つが、メソッドでパラメータを指定して各項目を更新することです。たとえば、updateCasePriority(String priority) という署名を使用して、ケースの優先度を更新するメソッドを作成できます。複数の項目を更新するには、目的のすべての項目をパラメータとしてリストします。
または、リクエストボディで項目を JSON の名前/値ペアとして渡します。後者の方が柔軟性が高くなります。こうすることで、メソッドは任意の数のパラメータを受け入れることができ、パラメータがメソッドの署名で固定されなくなります。この方法には、null になることが原因で誤って項目がクリアされることがないという利点もあります。CaseManager クラスに追加した updateCaseFields メソッドは、この 2 番目の方法を使用します。この方法では、リクエストボディの JSON 文字列を名前/値ペアの対応付けに並列化し、sObject PUT メソッドを使用して項目を設定します。
@HttpPatch global static ID updateCaseFields() { RestRequest request = RestContext.request; String caseId = request.requestURI.substring( request.requestURI.lastIndexOf('/')+1); Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId]; // Deserialize the JSON string into name-value pairs Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring()); // Iterate through each parameter field and value for(String fieldName : params.keySet()) { // Set the field and value on the Case sObject thisCase.put(fieldName, params.get(fieldName)); } update thisCase; return thisCase.Id; }
- ワークベンチ REST Explorer で、[PATCH] をクリックします。
- URI として「/services/apexrest/Cases/<Record ID>」と入力します。<Record ID> を、前に作成したケースレコードの ID に置き換えます。次の JSON をリクエストボディに入力します。
{ "status" : "Escalated", "priority" : "High" }
この JSON には、status と priority の 2 つの項目値があります。updateCaseFields メソッドは、送信された JSON からこれらの値を取得します。これらの値は、更新するオブジェクト項目を指定するために使用されます。
-
[実行] をクリックします。
この要求は、REST サービスで updateCaseFields メソッドを呼び出します。ケースレコードの [状況] および [優先度] 項目が新しい値に更新されます。これらの項目を確認するには、https://yourInstance.salesforce.com/<Record ID> に移動して Salesforce のこのレコードを表示します。
Apex REST クラスのテスト
次に、Apex REST サービスをテストする一般的な方法を示します。REST 要求をシミュレーションするには、次のようにテストメソッドで RestRequest を作成し、要求のプロパティを設定します。また、要求で「渡す」パラメータを追加して URI パラメータをシミュレーションすることもできます。
// Set up a test request RestRequest request = new RestRequest(); // Set request properties request.requestUri = 'https://yourInstance.salesforce.com/services/apexrest/Cases/' + recordId; request.httpMethod = 'GET'; // Set other properties, such as parameters request.params.put('status', 'Working'); // more awesome code here.... // Finally, assign the request to RestContext if used RestContext.request = request;
テストするメソッドが RestContext を介して要求値にアクセスする場合、要求を RestContext に割り当てて、要求 (RestContext.request = request;) を入力します。
次に、開発者コンソールでクラス全体を保存し、結果を実行します。
- 開発者コンソールで、 を選択します。
- クラス名として「CaseManagerTest」と入力し、[OK] をクリックします。
- 自動生成されるコードを次のクラス定義で置き換えます。
@IsTest private class CaseManagerTest { @isTest static void testGetCaseById() { Id recordId = createTestRecord(); // Set up a test request RestRequest request = new RestRequest(); request.requestUri = 'https://yourInstance.salesforce.com/services/apexrest/Cases/' + recordId; request.httpMethod = 'GET'; RestContext.request = request; // Call the method to test Case thisCase = CaseManager.getCaseById(); // Verify results System.assert(thisCase != null); System.assertEquals('Test record', thisCase.Subject); } @isTest static void testCreateCase() { // Call the method to test ID thisCaseId = CaseManager.createCase( 'Ferocious chipmunk', 'New', 'Phone', 'Low'); // Verify results System.assert(thisCaseId != null); Case thisCase = [SELECT Id,Subject FROM Case WHERE Id=:thisCaseId]; System.assert(thisCase != null); System.assertEquals(thisCase.Subject, 'Ferocious chipmunk'); } @isTest static void testDeleteCase() { Id recordId = createTestRecord(); // Set up a test request RestRequest request = new RestRequest(); request.requestUri = 'https://yourInstance.salesforce.com/services/apexrest/Cases/' + recordId; request.httpMethod = 'GET'; RestContext.request = request; // Call the method to test CaseManager.deleteCase(); // Verify record is deleted List<Case> cases = [SELECT Id FROM Case WHERE Id=:recordId]; System.assert(cases.size() == 0); } @isTest static void testUpsertCase() { // 1. Insert new record ID case1Id = CaseManager.upsertCase( 'Ferocious chipmunk', 'New', 'Phone', 'Low', null); // Verify new record was created System.assert(Case1Id != null); Case case1 = [SELECT Id,Subject FROM Case WHERE Id=:case1Id]; System.assert(case1 != null); System.assertEquals(case1.Subject, 'Ferocious chipmunk'); // 2. Update status of existing record to Working ID case2Id = CaseManager.upsertCase( 'Ferocious chipmunk', 'Working', 'Phone', 'Low', case1Id); // Verify record was updated System.assertEquals(case1Id, case2Id); Case case2 = [SELECT Id,Status FROM Case WHERE Id=:case2Id]; System.assert(case2 != null); System.assertEquals(case2.Status, 'Working'); } @isTest static void testUpdateCaseFields() { Id recordId = createTestRecord(); RestRequest request = new RestRequest(); request.requestUri = 'https://yourInstance.salesforce.com/services/apexrest/Cases/' + recordId; request.httpMethod = 'PATCH'; request.addHeader('Content-Type', 'application/json'); request.requestBody = Blob.valueOf('{"status": "Working"}'); RestContext.request = request; // Update status of existing record to Working ID thisCaseId = CaseManager.updateCaseFields(); // Verify record was updated System.assert(thisCaseId != null); Case thisCase = [SELECT Id,Status FROM Case WHERE Id=:thisCaseId]; System.assert(thisCase != null); System.assertEquals(thisCase.Status, 'Working'); } // Helper method static Id createTestRecord() { // Create test record Case caseTest = new Case( Subject='Test record', Status='New', Origin='Phone', Priority='Medium'); insert caseTest; return caseTest.Id; } }
- CTRL+S キーを押して保存します。
- を選択して、組織のすべてのテストを実行します。
[Tests (テスト)] タブにテスト結果が表示されます。テスト実行が完了したら、[Overall Code Coverage (全体のコードカバー率)] ペインで CaseManager 行を確認します。カバー率が 100% になっています。
もうひとこと...
- Apex REST でサポートされているデータ型
- Apex REST では、パラメータおよび戻り値で次のデータ型がサポートされています。
- Apex REST エンドポイントの名前空間
- Apex REST メソッドは、管理パッケージと未管理パッケージで使用できます。管理パッケージに含まれる Apex REST メソッドをコールする場合、REST のコール URL に管理パッケージの名前空間を含める必要があります。たとえば、packageNamespace という管理パッケージ名前空間にクラスが含まれており、Apex REST メソッドが /MyMethod/* という URL 対応付けを使用している場合、これらのメソッドをコールするために REST によって使用される URL は、https://instance.salesforce.com/services/apexrest/packageNamespace/MyMethod/ という形式になります。
- カスタム Apex Web サービスと Salesforce API
- REST および SOAP サービスのカスタム Apex コードを使用する代わりに、Salesforce の REST および SOAP API を使用して、外部アプリケーションを Salesforce と統合できます。これらの API では、レコードの作成、更新、削除ができます。ただし、Apex Web サービスを使用する利点は、Apex メソッドで複雑なロジックをカプセル化できることです。このロジックは、消費アプリケーションから隠ぺいされます。また、クライアントと Salesforce サーバ間で実行される往復処理が少なくなるため、Apex クラスの処理が個々の API コールを実行するよりも高速になる可能性があります。Apex Web サービスコールでは、1 つの要求のみが送信され、メソッド内の処理はすべてサーバで実行されます。
- Apex Web サービスのセキュリティに関する考慮事項
- Apex Web サービスメソッドが実行されるセキュリティコンテキストは、Salesforce API のセキュリティコンテキストとは異なります。Salesforce API とは異なり、Apex Web サービスメソッドはシステム権限で実行され、ユーザのオブジェクト権限や項目権限は考慮されません。ただし、Apex Web サービスメソッドが with sharing キーワードで宣言されている場合は、共有ルールが適用されます。
リソース
- Apex 開発者ガイド: Apex REST の概要
- Apex 開発者ガイド: Apex クラスを REST Web サービスとして公開
- Apex 開発者ガイド: Apex メソッドを SOAP Web サービスとして公開
- REST API 開発者ガイド: REST での cURL の使用例
- Creating REST APIs Using Apex REST (Apex REST を使用した REST API の作成)
- RFC7231 - HTTP 1.1 に関する情報 (要求メソッドや応答を含む)
- ウィキペディア: Representational state transfer (REST)
- Salesforce Developers: REST API
- cURL ドキュメント