Salesforce REST API 複合リソースを使えるようになろう!

# はじめに
　今回「Salesforce REST API 複合リソース」について検証しようとしたきっかけは、プロジェクトで利用する予定があり、更に今年のTrailheaDXで今後GraphQLの機能拡張されるというアナウンスがされたので決めました。
　この機能の最初の印象は、「フルカスタム画面の開発や他システムからの連携に便利なAPI」と感じました。ただ、初めて聞く人にとっては、情報があまり公開されていないので、トライアンドエラーで学習するには、少し難しいという印象を受けました。
　このブログで、初めて聞く人にとって「やってみようかなー」と思えるような内容にしたいと考えています。

# 機能概要
複合リソースについて下記にまとめる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/26510914-8e22-09a3-2c52-f673726f4c77.png)

[REST APIリファレンス：複合リソース](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/resources_composite.htm)

# 活用ユースケース
　Salesforceをデータベースとして、フルカスタムで画面を構築する場合や、他システムの画面操作でSalesforceにリアルタイム同期でデータ連携したい場合に有効だと言える。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/8618c481-dccc-435f-480c-981e000bc305.png)

# 各リソースの特徴について
 各複合リソースの特徴は以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/95871326-30a3-d5f6-c93b-cebb04832299.png)

# 各リソースのできる事・できない事
　各リソースのデータ操作については以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/d86b7cad-eb82-ce7b-e7bf-40c8a69d7350.png)

　その他の利用できるAPIについては以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/61a28ec8-f52c-75a4-d119-d0d772c92855.png)

### APIの説明
- Limits：組織の制限情報。
- Actions : アクションの呼び出し。

# 各リソースのサンプルを確認する
　各リソースを利用する際のリクエストについて説明する。

## Composite
　複数のREST APIへのリクエストをJSON形式に記述してリストにまとめることで、一つの呼び出しでまとめて実行する。"referenceID"に実行結果が格納され別のリクエストに情報を受け渡す。アクセス方法は、Javascriptの変数のようにアクセスする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/3eaf27a8-a1ee-0c3a-26dd-7ac0a43771a8.png)
↓サンプル

``` json
// Composite リソース サンプル
URL: https://<私のドメイン>.my.salesforce.com/services/data/v49.0/composite
METHOD: POST
HEADER:
	Authorization: Bearer <アクセストークン>
	Content-Type: application/json
REQUEST BODY:
{
	"compositeRequest" : [
	{
		"method" : "POST",
		"url" : "/services/data/v49.0/composite/sobjects",
		"referenceId" : "refNewAccount1",
		"body" : {
			"records" :[{
				"attributes" : {"type" : "Account"},
				"Name" : "Composite SObject1"
			}]
		}
	},{
		"method" : "POST",
		"url" : "/services/data/v49.0/composite/sobjects",
		"referenceId" : "refNewAccount2",
		"body" : {
			"records" :[{
				"attributes" : {"type" : "Account"},
				"Name" : "Composite SObject2"
			}]
		}
	}]
}
```

　ロールバックされた場合、問題のあるレコードに原因のメッセージが設定され、その他のロールバックされたレコードはロールバックのメッセージが設定される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/63a00835-aaae-db0d-8ab4-6ff8a26b55ff.png)

## Batch
　記述の仕方はCompositeと同じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/fd39a7e0-012a-d8ab-3f26-22f0a20c63bb.png)
↓サンプル

``` json
// Batch リソース サンプル
URL: https://<私のドメイン>.my.salesforce.com/services/data/v49.0/composite/batch
METHOD: POST
HEADER:
	Authorization: Bearer <アクセストークン>
	Content-Type: application/json
REQUEST BODY:
{
    "batchRequests" : [{
		"method" : "POST",
		"url" : "/services/data/v38.0/sobjects/Account",
		"richInput" : { "Name" : "Batch company 1"}
	},{
		"method" : "POST",
		"url" : "/services/data/v38.0/sobjects/Account",
		"richInput" : { "Name" : "Batch company 2"}
	}]
}
```

## SObject Tree
　URIパラメータで設定したオブジェクトのレコードをルートに持ち、親子関係のレコードをツリー構造に入れ子にして記述する。ツリー構造のデータをリストにまとめて実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/f1b1fd8e-1865-f78d-3e25-ae34691fcb2b.png)
↓サンプル

``` json
// SObject Tree リソース サンプル
URL: https://<私のドメイン>.my.salesforce.com/services/data/v49.0/composite/tree/Account
METHOD: POST
HEADER:
	Authorization: Bearer <アクセストークン>
	Content-Type: application/json
REQUEST BODY:
{
"records" :[{
    "attributes" : {"type" : "Account", "referenceId" : "ref1"},
    "name" : "SObject Tree 1",
    "phone" : "1234567890",
    "website" : "www.salesforce.com",
    "numberOfEmployees" : "100",
    "industry" : "Banking",
    "Contacts" : {
      "records" : [{
         "attributes" : {"type" : "Contact", "referenceId" : "ref2"},
         "lastname" : "SObject Tree 2",
         "title" : "President"
         },{         
         "attributes" : {"type" : "Contact", "referenceId" : "ref3"},
         "lastname" : "SObject Tree 3",
         "title" : "Vice President"
         }]
      }
    }]
}
```

## SObject Collection
　複数のレコードをSObjectに紐づけてリストにまとめて実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/c522cd44-30c1-6e1e-afd5-a1e8be949c52.png)
↓サンプル

``` json
// SObject Collection リソース サンプル
URL: https://<私のドメイン>.my.salesforce.com/services/data/v49.0/composite/sobjects
METHOD: POST
HEADER:
	Authorization: Bearer <アクセストークン>
	Content-Type: application/json
REQUEST BODY:
{
   "allOrNone" : false,
   "records" : [{
      "attributes" : {"type" : "Account"},
      "Name" : "Company1"
   }, {
      "attributes" : {"type" : "Contact"},
      "LastName" : "Kawaguchi1",
      "FirstName" : "Masaki"
   }]
}
```

# まとめ
　Salesforce REST API 複合リソースは、これまでプログラムで実装していた複数のリソース情報の取得処理やトランザクション処理、データ加工処理を標準機能として提供してくれます。本当に便利な機能ですね。
　ご紹介した活用のユースケースにマッチする要件がある場合にはぜひ利用してみてください。
　また、TrailHeaDXでは、今後、GraphQLの機能拡張をするとアナウンスしています。対応されることにより、画面開発者にとってより便利な機能になるのではないでしょうか？。
　私は、SObject TreeをSalesforce DXのクローズドパイロットの期間に初めて知って、今回キャッチアップしたことによって、色々なAPIが増えてとてもビックリしました。また、今のキャッチアップできてとてもよかったと思います。
それでは、APIライフをエンジョイしてくださいー。では！