概要
- Apex クラスメソッドを REST または SOAP Web サービス処理として公開可能
- メソッドを Web 経由でコールできるようにすることで、外部アプリケーションと Salesforce を統合可能
#ApexクラスをREST Webサービスとして使用する
- クラスの定義、メソッドはGlobalにする(メソッドはstaticにしておく)
- アノテーション (@hoge) を下記のように定義する
- getRecord()
メソッドはカスタムREST APIコール。GET要求で呼び出される。
@RestResource(urlMapping='/Account/*') global with sharing class MyRestResource { @HttpGet global static Account getRecord() { // Add your code } }
- @RestResourceについて
- Apex RESTのベースエンドポイントは
https://yourInstance.my.salesforce.com/services/apexrest/
- 上記例だと
https://yourInstance.my.salesforce.com/services/apexrest/Account/*
となる
- Apex RESTのベースエンドポイントは
アノテーション | アクション | 詳細 |
---|---|---|
@HttpGet | 参照 | レコードを参照または取得します。 |
@HttpPost | 作成 | レコードを作成します。 |
@HttpDelete | 削除 | レコードを削除します。 |
@HttpPut | 更新/挿入 | 通常、既存のレコードを更新したり、レコードを作成したりするために使用します。 |
@HttpPatch | 更新 | 通常、既存のレコードの項目を更新するために使用します。 |
ApexクラスをSOAP Webサービスとして使用する
- RESTとほぼ同じだが、メソッドに
webservice
キーワードを追加する- 上記メソッドはGlobal扱いになる
global with sharing class MySOAPWebService { webservice static Account getRecord(String id) { // Add your code } }
Session IDの取得
- REST エンドポイントを「cURL」するたびに、認証用のセッション ID が渡される
設定方法は下記
developer.salesforce.com下記を実行し、成功した場合の
access_token
が Session ID
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"
- 下記を実行するとレコードが返される。
- Trailheadの構文のままやると
zsh: event not found
となったので下記で実施
curl https://yourInstance.my.salesforce.com/services/apexrest/Cases/<Record_ID> -H 'Authorization: Bearer <your_session_id>' -H "X-PrettyPrint:1"
PATCHメソッド
レコードの項目を更新する際に使用するらしい
やり方は2つ。
1. メソッドでパラメータを指定して各項目を更新(更新したい項目ごとにメソッドを定義する必要がある)
2. リクエストボディでJSONの名前/値のペアで渡す (こちらの方が柔軟性は高い)
例のソースは方法2.
@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; }
Apex RESTクラスのテスト
- テストメソッドで
RestRequest
を作成し、要求のプロパティを設定する
// Set up a test request RestRequest request = new RestRequest(); // Set request properties request.requestUri = 'https://yourInstance.my.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;
Challenge
なんでか知らんがこのコードならPass.
urlMappingはこうじゃないとダメっぽい.
@RestResource(urlMapping='/Accounts/*/contacts')
NG: @RestResource(urlMapping='/Accounts/*/Contacts')
@RestResource(urlMapping='/Accounts/*/contacts') global with sharing class AccountManager { @HttpGet global static Account getAccount() { RestRequest request = RestContext.request; system.debug(request.requestURI); // grab the caseId from the end of the URL String accountId = request.requestURI.substringBetween('/Accounts/', '/contacts'); Account result = [SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account WHERE Id = :accountId]; return result; } }
@IsTest private class AccountManagerTest { @isTest static void testgetAccount() { Id accountRecordId = createTestAccountRecord(); // Set up a test request RestRequest request = new RestRequest(); request.requestUri = 'https://yourinstance.my.salesforce.com/services/apexrest/Accounts/' + accountRecordId + '/contacts'; request.httpMethod = 'GET'; RestContext.request = request; // Call the method to test Account thisAccount = AccountManager.getAccount(); // Verify results System.assert(thisAccount != null); System.assertEquals('Test record', thisAccount.Name); } // Helper method static Id createTestAccountRecord() { // Create test record Account accountTest = new Account(Name='Test record'); insert accountTest; Contact contactTest = new Contact(AccountId=accountTest.Id, FirstName='TestFirstName', LastName='TestLastName'); insert contactTest; return accountTest.Id; } }