Salesforce記録④:salesforceから(AWS、別Server) HTTP API Gatewayにアクセスする(202406)

##### Salesforce リモートサイト設定：
リモートサイトの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3802240/816a45b3-a75e-2c74-42ee-fbf7a1bb50a8.png)
Http URLを追加する

##### トリガーやBatchを作成する(ここではトリガーで作成する)

##### トリガー
``` Trigger
trigger HandleInsertAndUpdate on YourObject__c (before insert, after insert, before update, after update) {
    
    // Before Insert
    if (Trigger.isBefore && Trigger.isInsert) {
        for (YourObject__c newRecord : Trigger.New) {
         
            }
        }
    //ここでQueueable処理を呼ぶ
        System.enqueueJob(new AwsApiQueueable(Trigger.New, 'BeforeInsert'));
        
    }
    
    // After Insert
    if (Trigger.isAfter && Trigger.isInsert) {
        for (YourObject__c newRecord : Trigger.New) {
           
        }
    }
    
    // Before Update
    if (Trigger.isBefore && Trigger.isUpdate) {
        for (YourObject__c newRecord : Trigger.New) {
           
        }
    }
    
    // After Update
    if (Trigger.isAfter && Trigger.isUpdate) {
        for (YourObject__c newRecord : Trigger.New) {
          
        }
    }
}

```
Salesforceでは、トリガーから外部システムへの直接の呼び出し（HTTPコールアウト）はサポートされていません。これは、トリガーがデータベーストランザクション内で実行されるため、外部呼び出しがトランザクションの不確実性や複雑性を増す可能性があるためです。この制限を回避するために、以下のいずれかの方法を使用して外部サービスを非同期で呼び出すことができます：

1.Queueable Apex（キュー可能Apex）
2.Future Methods（フューチャーメソッド）
3.Batch Apex（バッチApex）

##### Queueable Apexを作成する
##### Queueable 1件ずつ処理する APIをcallする
```
public class AwsApiQueueable implements Queueable, Database.AllowsCallouts {
    private List<String> recordIds;
    private String action;

    // 構造関数
    public AwsApiQueueable(List<String> recordIds, String action) {
        this.recordIds = recordIds;
        this.action = action;
    }

    public void execute(QueueableContext context) {
        for (String recordId : recordIds) {
            // APIの処理が1件制限の場合
            HttpRequest req = new HttpRequest();
            HttpResponse res = new HttpResponse();
            Http http = new Http();

            //  AWS API URL
            String url = 'https://api.example.com/your-endpoint';
            req.setEndpoint(url);
            req.setMethod('POST');
            req.setHeader('Content-Type', 'application/json');
            req.setHeader('x-api-key', 'YOUR_API_KEY_HERE');

            // JSON 
            Map<String, Object> requestData = new Map<String, Object>();
            requestData.put('recordId', recordId);
            requestData.put('action', action);

            String jsonBody = JSON.serialize(requestData);
            req.setBody(jsonBody);

            // send request
            try {
                res = http.send(req);

                if (res.getStatusCode() == 200) {
                    // Response処理
                    System.debug('Response: ' + res.getBody());
                } else {
                    // error処理
                    System.debug('Error: ' + res.getStatus() + ' - ' + res.getBody());
                }
            } catch (Exception e) {
                // exception処理
                System.debug('Exception: ' + e.getMessage());
            }
        }
    }
}

```

##### Queueable 10件ずつ　APIをcallする
```
public class AwsApiQueueable implements Queueable, Database.AllowsCallouts {
    private List<String> recordIds;
    private String action;

    // コンストラクタ、リストとアクションを受け取る
    public AwsApiQueueable(List<String> recordIds, String action) {
        this.recordIds = recordIds;
        this.action = action;
    }

    public void execute(QueueableContext context) {
        // リストを10件ずつのバッチに分割
        for (Integer i = 0; i < recordIds.size(); i += 10) {
            List<String> batch = recordIds.subList(i, Math.min(i + 10, recordIds.size()));
            sendBatchRequest(batch);
        }
    }

    private void sendBatchRequest(List<String> batch) {
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();

        // 設定 AWS API の URL
        String url = 'https://api.example.com/your-endpoint';
        req.setEndpoint(url);
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('x-api-key', 'YOUR_API_KEY_HERE');

        // JSON データを作成
        Map<String, Object> requestData = new Map<String, Object>();
        requestData.put('recordIds', batch);
        requestData.put('action', action);

        String jsonBody = JSON.serialize(requestData);
        req.setBody(jsonBody);

        // リクエストを送信し、レスポンスを受信
        try {
            res = http.send(req);

            if (res.getStatusCode() == 200) {
                // 成功レスポンスの処理
                System.debug('Response: ' + res.getBody());
            } else {
                // エラーレスポンスの処理
                System.debug('Error: ' + res.getStatus() + ' - ' + res.getBody());
            }
        } catch (Exception e) {
            // 例外の処理
            System.debug('Exception: ' + e.getMessage());
        }
    }
}

```

##### 10件ごとに1回の呼び出しを Queueable クラスの execute メソッドで処理する
10件ごとに1回の呼び出しを Queueable クラスの execute メソッドで処理する場合、レコードIDのリストを分割し、それぞれの部分ごとに Queueable ジョブをキューに入れることができます。これにより、各 Queueable ジョブは最大10件のレコードIDを処理します。


```
trigger HandleInsertAndUpdate on YourObject__c (before insert, after insert, before update, after update) {
    
    // Before Insert
    if (Trigger.isBefore && Trigger.isInsert) {
        Integer batchSize = 10;
        // レコードIDのリストを10件ずつのバッチに分割してジョブをキューに入れる
        for (Integer i = 0; i < recordIds.size(); i += batchSize) {
            List<String> batch = recordIds.subList(i, Math.min(i + batchSize, recordIds.size()));
            AwsApiQueueable job = new AwsApiQueueable(batch, action);
            System.enqueueJob(job);
        }
}

```

```
public class AwsApiQueueable implements Queueable, Database.AllowsCallouts {
    private List<String> recordIds;
    private String action;

    // コンストラクタ、リストとアクションを受け取る
    public AwsApiQueueable(List<String> recordIds, String action) {
        this.recordIds = recordIds;
        this.action = action;
    }

    public void execute(QueueableContext context) {
        // 各レコードに対して操作を実行
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();

        // 設定 AWS API の URL
        String url = 'https://api.example.com/your-endpoint';
        req.setEndpoint(url);
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('x-api-key', 'YOUR_API_KEY_HERE');

        // JSON データを作成
        Map<String, Object> requestData = new Map<String, Object>();
        requestData.put('recordIds', recordIds);
        requestData.put('action', action);

        String jsonBody = JSON.serialize(requestData);
        req.setBody(jsonBody);

        // リクエストを送信し、レスポンスを受信
        try {
            res = http.send(req);

            if (res.getStatusCode() == 200) {
                // 成功レスポンスの処理
                System.debug('Response: ' + res.getBody());
            } else {
                // エラーレスポンスの処理
                System.debug('Error: ' + res.getStatus() + ' - ' + res.getBody());
            }
        } catch (Exception e) {
            // 例外の処理
            System.debug('Exception: ' + e.getMessage());
        }
    }
}

```
最後にリモートサイトの設定を追加する(訪問先のSITE　URL)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3802240/2016f0a3-4f86-9903-7796-ef6e8ae51c3a.png)

例：https://api.example.com