Salesforce Apex で独自の Salesforce REST API を作成する (取引先責任者をLIKE検索して表示)

はじめに
===

本資料では、独自のSalesforce REST APIを作成する手順について記しています。

　**(1) Salesforce Apexクラスを作成し、独自のSalesforce REST APIを作成する手順**
　**(2) PHPから作成したSalesforce REST APIを実行するサンプルコード**

参考資料
===

ApexによるSalesforce REST API作成については、以下の資料を参考にさせて頂きました。ありがとうございました。

http://kayakuguri.github.io/blog/2014/09/08/apex-restapi/
https://developer.salesforce.com/page/Creating_REST_APIs_using_Apex_REST

Apexで独自に作成したSalesforce REST APIについては、以下の手順により構築したAmazon EC2インスタンス(Amazon Linux)上で実行しています。

http://qiita.com/na0AaooQ/items/157c28a80948c4b97bed
 
Apexクラスで独自のSalesforce REST APIを作成する
===

## (1) https://login.salesforce.com/ へログインします。

## (2)「設定」->「ビルド」->「開発」->「Apexクラス」->「新規」をクリックします。

<img width="1272" alt="スクリーンショット 2017-03-14 1.54.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/854f2292-9133-db4d-5f3c-efddbe956522.png">

## (3)「Apex Class」画面が表示されます。Apexクラスを作成します。

「Apex Class Edit」テキストエリアに以下のApexコードを貼り付けます。

これは、取引先責任者(Contact)のName項目について、指定した文字列が含まれているレコードを返すApexクラスです。

例えば、今回作成するSalesforce REST APIに対して 'テスト' というパラメータをGETで指定した場合、取引先責任者(Contact)のName項目をLIKE検索して 'テスト' という文字列が含まれているレコードを返します。


```
@RestResource(urlMapping='/CustomContact/*')
global with sharing class CustomContactSample {
    @HttpGet
    global static sObject doGet() {
        RestRequest req = RestContext.request;
        String ContactName = req.params.get('name');
        ContactName = '%' + ContactName + '%';
        try {
            Contact acc = [SELECT Id, Name, Email, Account.Name FROM Contact WHERE Name LIKE :ContactName LIMIT 1];
            return acc;
        } catch (exception e) {
            return null;
        }
    }
}
```

「Save」をクリックして、Apexクラスを作成します。

<img width="1279" alt="スクリーンショット 2017-03-14 1.58.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/f6d953e0-5ae5-ffe7-6cac-ad05fd57b2b6.png">

## (4) 「設定」->「ビルド」->「開発」->「Apexクラス」をクリックします。Apexクラス「CustomContactSample」が作成されている事を確認します。

<img width="1249" alt="スクリーンショット 2017-03-14 2.01.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/b16b5703-7534-8770-6c38-86b9621fc6d9.png">

「CustomContactSample」をクリックします。先ほどApexクラス作成時に貼り付けたコードが表示される事を確認します。

<img width="1256" alt="スクリーンショット 2017-03-14 2.03.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/98a8a951-fa9b-8300-8714-48aa1d2ec81c.png">

## (5)「設定」->「管理」->「ユーザの管理」->「プロファイル」をクリックします。

<img width="1246" alt="スクリーンショット 2017-03-14 2.10.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/3afaa70f-c55f-3f95-c452-57a52ff3d95f.png">

## (6)「テストオブジェクトプロファイル」をクリックします。

## (7) プロファイル画面が表示されます。「有効な Apex クラス」をクリックします。

<img width="1247" alt="スクリーンショット 2017-03-14 2.12.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/72ef94b5-07c1-a517-998c-fccea3cd9fa7.png">

## (8)「有効な Apex クラス」の「編集」をクリックします。

<img width="1265" alt="スクリーンショット 2017-03-14 2.13.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/4082077d-83ae-b5c5-2fcb-68f541436e7e.png">

## (9)「Apex クラスアクセスを有効化」画面が表示されます。「利用可能な Apex クラス」で「CustomContactSample」を選択して「追加」をクリックします。

「有効化された Apex クラス」に「CustomContactSample」が追加された事を確認します。

<img width="1251" alt="スクリーンショット 2017-03-14 2.15.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/07828f18-98c0-96cc-80f4-7e72a59b7a7e.png">

## (10) .bashrcにSalesforce REST APIのクレデンシャルを追加します。

以下を参考にして、.bashrcにSalesforce REST APIクレデンシャルを追加します。

http://qiita.com/na0AaooQ/items/157c28a80948c4b97bed

.bashrcにSalesforce REST APIクレデンシャルを追加します。

```
[ec2-user@salesforce-api-test ~]$ vi /home/ec2-user/.bashrc
　(末尾に以下を追加する)

### Sandbox環境へ接続する場合のAPIエンドポイント
##export DATABASEDOTCOM_HOST="test.salesforce.com"
### 本番環境へ接続する場合のAPIエンドポイント
export DATABASEDOTCOM_HOST="login.salesforce.com"

export DATABASEDOTCOM_CLIENT_ID="前述の「コンシューマ鍵」(OAuthコンシューマキー)を記載します。"
export DATABASEDOTCOM_CLIENT_SECRET="前述の「コンシューマの秘密」(OAuthコンシューマシークレット)を記載します。"
export DATABASEDOTCOM_CLIENT_USERNAME="APIを有効化しているSalesforceユーザアカウント名を記載します。"
export DATABASEDOTCOM_CLIENT_AUTHENTICATE_PASSWORD="APIを有効化しているSalesforceユーザアカウントのパスワードを記載します。"
```

.bashrcに追加した環境変数を読み込みます。

```
[ec2-user@salesforce-api-test ~]$ source /home/ec2-user/.bashrc
[ec2-user@salesforce-api-test ~]$ 
```

作成した独自のSalesforce REST APIをPHPから実行する
===

## (11) 独自に作ったSalesforce REST APIを呼び出すPHPサンプルプログラムを作成します。

```
[ec2-user@salesforce-api-test ~]$ php -v
PHP 5.3.29 (cli) (built: May 12 2015 22:42:19) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
[ec2-user@salesforce-api-test ~]$ 
```

```
[ec2-user@salesforce-api-test ~]$ vi /home/ec2-user/select_salesforce_custom_api_contact.php
```

```php:/home/ec2-user/select_salesforce_custom_api_contact.php
<?php
 
require_once("/home/ec2-user/Force.com-OAuth-Toolkit-for-PHP/oauth.php");

if ( $argc == 2 ) {
  $name = "$argv[1]";
}
else {
  echo "[Usage]: $argv[0] テスト\n";
  exit;
}

///// Salesforce REST API接続用の環境変数を.bashrcから取得する
// Salesforce REST APIで接続するアプリケーションの「コンシューマ鍵」
$DATABASEDOTCOM_CLIENT_ID = getenv('DATABASEDOTCOM_CLIENT_ID');
 
// Salesforce REST APIで接続するアプリケーションの「コンシューマの秘密」を.bashrcから取得する
$DATABASEDOTCOM_CLIENT_SECRET = getenv('DATABASEDOTCOM_CLIENT_SECRET');
 
// Salesforce REST API接続用のSalesforceユーザ(Salesforceログインに使用しているEメールアドレスを設定)を.bashrcから取得する
$DATABASEDOTCOM_CLIENT_USERNAME = getenv('DATABASEDOTCOM_CLIENT_USERNAME');
 
// Salesforce REST API接続用のSalesforceユーザのパスワードを.bashrcから取得する
$DATABASEDOTCOM_CLIENT_AUTHENTICATE_PASSWORD = getenv('DATABASEDOTCOM_CLIENT_AUTHENTICATE_PASSWORD');
 
// Salesforce REST APIエンドポイントを.bashrcから取得する
$DATABASEDOTCOM_HOST = getenv('DATABASEDOTCOM_HOST');
$LOGIN_URL = "https://" . $DATABASEDOTCOM_HOST . "/";
 
///// Salesforce REST API接続用の設定
$CACHE_DIR = '/home/ec2-user/tmp/session';
$CALLBACK_URL = 'https://localhost/callback';

/////
// Salesforce REST API接続用のOauthインスタンスを生成
$oauth = new oauth( $DATABASEDOTCOM_CLIENT_ID, $DATABASEDOTCOM_CLIENT_SECRET, $CALLBACK_URL, $LOGIN_URL, $CACHE_DIR);
 
// Salesforce REST API接続にあたりSalesforceへの認証を実行
$oauth->auth_with_password( $DATABASEDOTCOM_CLIENT_USERNAME, $DATABASEDOTCOM_CLIENT_AUTHENTICATE_PASSWORD );
 
// カスタムAPIのURLを指定する
$url = $oauth->instance_url . "/services/apexrest/CustomContact/?name=" . $name;
$curl = curl_init($url);
var_dump($url);
 
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: OAuth " . $oauth->access_token));
 
// Salesforce REST API実行結果を保存
$response = json_decode(curl_exec($curl), true);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
 
if ( $status != 200 ) {
    print("Salesforce Custom REST API Access Failed  StatusCode =[" . $status . "]\n");
} else {
    print("Salesforce Custom REST API Access Success StatusCode =[" . $status . "]\n");
}
 
var_dump( $response );

curl_close($curl);
 
$oauth->auth_with_refresh_token();
 
?>
```

## (12) 作成したPHPサンプルプログラムの構文に問題ない事をチェックします。

```
[ec2-user@salesforce-api-test ~]$ php -l /home/ec2-user/select_salesforce_custom_api_contact.php 
No syntax errors detected in /home/ec2-user/select_salesforce_custom_api_contact.php
[ec2-user@salesforce-api-test ~]$ 
```

## (13) PHPサンプルプログラムを実行し、独自に作ったSalesforce REST APIを呼び出します。

PHPサンプルプログラムを実行すると、独自に作ったSalesforce REST APIを呼び出します。

以下の例では、Salesforce REST APIに対して 'テスト' というパラメータをGETで渡して、取引先責任者(Contact)のName項目をLIKE検索して 'テスト' という文字列が含まれているレコードを表示しています。


```
[ec2-user@salesforce-api-test ~]$ php /home/ec2-user/select_salesforce_custom_api_contact.php テスト
string(74) "https://ap2.salesforce.com/services/apexrest/CustomContact/?name=テスト"
Salesforce Custom REST API Access Success StatusCode =[200]
array(6) {
  ["attributes"]=>
  array(2) {
    ["type"]=>
    string(7) "Contact"
    ["url"]=>
    string(56) "/services/data/v39.0/sobjects/Contact/00**************AS"
  }
  ["Id"]=>
  string(18) "00**************AS"
  ["Name"]=>
  string(16) "テスト 太郎"
  ["Email"]=>
  string(19) "example@example.com"
  ["AccountId"]=>
  string(18) "00**************AH"
  ["Account"]=>
  array(3) {
    ["attributes"]=>
    array(2) {
      ["type"]=>
      string(7) "Account"
      ["url"]=>
      string(56) "/services/data/v39.0/sobjects/Account/00**************AH"
    }
    ["Id"]=>
    string(18) "00**************AH"
    ["Name"]=>
    string(21) "テスト株式会社"
  }
}
[ec2-user@salesforce-api-test ~]$ 
```

今回のAPIでは、取引先責任者の「テスト 太郎」のレコードを表示しています。

<img width="1254" alt="スクリーンショット 2017-03-14 2.28.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/63647/dd213fe0-476a-da86-0a36-f25eb5375093.png">

***

以上になります。