Apex Web サービス
クラス2つ作る。
1.
class ①
動作する。AccountManager.apex
@RestResource(urlMapping='/Accounts/*/contacts') global with sharing class AccountManager { @HttpGet global static Account getAccount(){ RestRequest request = RestContext.request; // grab the accoutId from the end of the URL List<String> paramList = request.requestURI.split('/'); Integer accIdNum = paramList.size()-2; String accountId = paramList[accIdNum]; Account result = [SELECT Id, Name, (Select id, name from Contacts) FROM Account WHERE Id = :accountId]; return result; } }
2.
class ②
class ①をテストする。AccountManagerTest.apex
@isTest private class AccountManagerTest { @isTest static void testGetAccount(){ Id recordId = createTestRecord(); RestRequest request = new RestRequest(); request.requestURI = 'https://curious-hawk-6yiw16-dev-ed.salesforce.com/services/apexrest/Accounts/'+ recordId +'/contacts' ; request.httpMethod = 'GET'; RestContext.request = request; Account thisAcc = AccountManager.getAccount(); System.assert(thisAcc != null); System.assertEquals('dotoru', thisAcc.Name); } //Helper method static Id createTestRecord(){ //Create test record Account accountTest = new Account( Name = 'dotoru'); insert accountTest; return accountTest.Id; } }
迷ったのは、
- urlの真ん中にあるパラメータ(*で書いてあるレコードId)をどう取得するか
String accid= request.requestURI.substringBetween('Accounts/','/contacts');
こんな方法もあった!
- challenge確認 ERROR
Account result = [SELECT Id, Name FROM Account WHERE Id = :accountId];
AccountManager.apexここでSOQL文をこんな感じで書いてたら、エラーでパスができない!
Executing the 'AccountManager' method failed. Either the service isn't configured with the correct urlMapping, is not global, does not have the proper method name or does not return the requested account and all of its contacts.
探してみたら、Contactsの情報も取得することでパスできた!!
Account result = [SELECT Id, Name, (Select id, name from Contacts) FROM Account WHERE Id = :accountId];
cURLどうするの?
モジュールの中でcURLを使い、REST クライアントを使用することがあった。
cURLはうまくできなかった。
... ... "error" : "invalid_grant", "error_description" : "authentication failure" * Connection #0 to host login.salesforce.com left intact
Plz go to Create --> App --> Connected App. click on "connected app" then click on "Manage" button. On click, you have to change "IP Relaxation" setting to "Relax IP Restrictions". With this setting you can resolve such issue.
これもやってみたけど、できなかったから、諦めてる。
Apex SOAP コールアウト
2.
class ① 作成 「ParkLocator.apex」
xmlのメソッドを呼び出すApex
public class ParkLocator { public static List<String> country(String pCountry){ ParkService.ParksImplPort park = new ParkService.ParksImplPort(); return park.byCountry(pCountry); } }
3.
class ② 作成 「ParkServiceMock.apex」
class ①で呼び出したメソッドの結果を指定するモック
@isTest global class ParkServiceMock implements WebSErviceMock{ global void doInvoke( Object stub, Object request, Map<String, Object> response, String endpoint, String soapAction, String requestName, String responseNS, String responseName, String responseType) { //start - specify the response you want to send ParkService.byCountryResponse response_x = new ParkService.byCountryResponse(); //Germany, India, Japan and United States. List<String> countries = new List<String>(); countries.add('Yoyogi'); countries.add('Hibiya'); countries.add('Ueno'); response_x.return_x = countries; //end response.put('response_x',response_x); } }
補足:
1.
global
2.
implements WebSErviceMockのため、パラメータは
(
Object stub,
Object request,
Map
String endpoint,
String soapAction,
String requestName,
String responseNS,
String responseName,
String responseType)
これで決まり。
4.
class ③ 作成 「ParkLocatorTest.apex」
class ① をテストするためのApex
@isTest private class ParkLocatorTest { @isTest static void testCallout(){ //This causes a fake response to be generated Test.setMock(WebSErviceMock.class, new ParkServiceMock()); //Call the method that invikese to be generated String country = 'Japan'; List<String> result = ParkLocator.country(country); List<String> countries = new List<String>(); countries.add('Yoyogi'); countries.add('Hibiya'); countries.add('Ueno'); System.assertEquals(countries,result); } }
大きい概念は
class ①をテストするためにclass ③ を作るが、
これだけではテストがうまく行かないため、
class ②の仮想の結果を指定しておく。
■
The 'Cleaner' profile does not have read only permission for all other standard objects besides account, contact and lead.
but only have edit rights on Accounts, Contacts, and Leads.
Read Onlyプロファイルを複製して、Accounts, Contacts, and LeadsのEditをチェック下が、
Could not find a Chatter group named 'Sales Team'.
再読み込み、グループの写真設定、投稿
リンクマークを使うのではなく、下記のコメントを入力すると自動的にリンクされる。
http://developer.salesforce.com/trailhead - the best learning tool for Salesforce out there!
20190322Rookie会「Visualforce編」
HelloAccountEntry.vfp
<apex:page Controller="HelloAccountEntryController"> <apex:form > <apex:pageBlock title="HelloAccountEntry" mode="edit"> <apex:pageBlockButtons > <apex:commandButton action="{!save}" value="登録"/> </apex:pageBlockButtons> <apex:pageBlockSection title="My Content Section" columns="2"> <apex:inputField value="{!account.Name}"/> <apex:inputField value="{!account.Phone}"/> <apex:inputField value="{!account.Type}"/> <apex:inputField value="{!account.ParentId}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
HelloAccountEntryController.apex
public class HelloAccountEntryController { public Account account{get; set;} public HelloAccountEntryController(){ account = new Account(); } public PageReference save(){ insert account; // 入力欄を空白に // account = new Account(); return null; } }
1.コンストラクタ必要!(HelloAccountEntryController)
2.登録した後に入力を初期化したい場合は?登録後に、account = new Account();を書く。
HelloAccountList.vfp
<apex:page Controller="HelloAccountListController"> <apex:pageBlock title="HelloAccount"> <apex:pageBlockTable value="{!account}" var="item"> <apex:column value="{!item.Name}"/> <apex:column value="{!item.Phone}"/> <apex:column value="{!item.Website}"/> <apex:column value="{!item.OwnerId}"/> </apex:pageBlockTable> </apex:pageBlock> </apex:page>
HelloAccountListController.apex
public class HelloAccountListController { public List<Account> account{get; set;} public HelloAccountListController(){ account = [SELECT Name, Phone, Website, OwnerId FROM Account]; } }
1.テーブルの表示?PageBlockTableを利用
2.初期から表示したい場合は?コンストラクタを使い、表示するレコードを取得。(HelloAccountListController)
HelloBMI.vfp
<apex:page controller="HelloBMIController"> <apex:form > 身長:<apex:inputText value="{!height}" id="height"/>cm <br/> 体重:<apex:inputText value="{!weight}" id="weight"/>kg <br/> <apex:commandButton action="{!calBMI}" value="計算" id="theButton"/> <br/> BMI: <apex:outputText value="{!bmi}"> </apex:outputText> </apex:form> </apex:page>
HelloBMIController.apex
public class HelloBMIController { public String height{get; set;} public String weight{get; set;} public Double bmi{get; set;} public PageReference calBMI(){ this.bmi = Double.valueOf(weight) / ((Double.valueOf(height)/100)*(Double.valueOf(height)/100)); return null; } }
1.inputTextで入力した値を受け取るのはStringでいい。ex)String height,String weight
2.Stringだったため、Double.valueOfを使って計算する。
3.bmiはDoubleにして小数点以下の値が表示できるようにする。
HelloComponent.vfp
<apex:page > <!-- 「confirm」、「info」、「warning」、または「error」 --> <apex:pageMessage title="タイトル" summary="メッセージ" severity="confirm" strength="0" /> <apex:pageMessages /> <apex:pageMessage summary="This pageMessage will always display. Validation error messages appear in the pageMessages component." severity="info" strength="1" /> <apex:pageMessages /> <apex:pageMessage summary="This pageMessage will always display. Validation error messages appear in the pageMessages component." severity="error" strength="2" /> <apex:pageMessages /> <apex:pageMessage summary="This pageMessage will always display. Validation error messages appear in the pageMessages component." severity="warning" strength="3" /> <apex:pageMessages /> </apex:page>