B2C Commerce のその他 Salesforce 製品との接続 - HTTP,  FTP,  SOAP


※ これから記載する事項は、私が所属する会社とは切関係のない事柄です。


今回は[「B2C Commerce のその他 Salesforce 製品との接続」シリーズ](https://qiita.com/syunyama/items/366fcbc315be5e5c252f)として B2C Commerce から HTTP, FTP, SOAP を利用して Web サービスと接続する方法について紹介したいと思います。

![Cross Cloud (13).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/b7db5997-e71c-d1bd-8d96-e16a85a64016.jpeg)



## 他製品 API
下記の API に関する開発者ヘルプサイトのナビの「Discover」から Salesforce 製品の API 情報を確認できます。

https://developer.salesforce.com/docs/apis

![スクリーンショット 2023-03-30 17.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/46464832-6db1-115a-e0b7-c8bcdec6f04b.png)



## 接続内容とポイント

* 接続のタイプとしては HTTP、HTTP Form、FTP、 SFTP、SOAP、Generic（= カスタムして使う）がある
* デフォルトではBasic認証に対応している
* タイムアウト、レート制限、サーキットブレーカーの設定ができる
* [LocalServiceRegistry](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_svc_LocalServiceRegistry.html?resultof=%22%4c%6f%63%61%6c%53%65%72%76%69%63%65%52%65%67%69%73%74%72%79%22%20%22%6c%6f%63%61%6c%73%65%72%76%69%63%65%72%65%67%69%73%74%72%79%22%20) をコード内で利用してサービスを呼ぶ
* サービスごとに通信状況（平均呼出時間、成功率、失敗率など）を分析できる




## 接続方法

#### 前提

今回はシンプルに B2C Commerce に `/HttpTest-Show` ルートを作成して、 HTTP でリクエストした内容を返してくれる https://httpbin.org にベーシック認証で POST した結果を表示してみたいと思います。

下記のようにリクエストした結果を

```sh
REQUEST:
POST /anything 
Host: httpbin.org
Authorization: Basic {credentials}
Content-Type: application/json

BODY:
{
    "test": "テスト"
}
```

下記のように画面に表示されるようにします。
![スクリーンショット 2023-03-30 14.57.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/857711b2-2771-cfce-33a8-37144f969b71.png)





#### 1. サービス、プロフィール、認証情報の設定

**管理 > オペレーション > サービス** に遷移して「サービス」タブをクリックし、「新規」ボタンを押すと下記のような入力画面が表示される。今回は `profile.httpbin.org` という名前を持つサービスプロフィールを作成します。
![image (48).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/655cc23f-f01b-73c2-64e6-002517545740.png)




**管理 > オペレーション > サービス** に遷移して「認証情報」タブをクリックし、「新規」ボタンを押すと下記のような入力画面が表示される。今回は `auth.httpbin.org` という名前を持つサービス認証情報を作成します。
この際に Basic 認証に利用する ユーザ（ID）、パスワードを入力します。

![image (49).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/e67a00ec-77d2-f904-c8ed-d35a8984e493.png)



**管理 > オペレーション > サービス** に遷移して「サービス」タブをクリックし、「新規」ボタンを押すと下記のような入力画面が表示される。今回は `httpbin.org` という名前を持つサービスを作成します。
この際に上記で設定したプロフィール、認証情報を設定します。

![image (50).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/3b2a818d-6f61-93bc-d44d-22220f020b85.png)



#### 2. テストコード

下記のコードで `/HttpTest-Show` にリクエストがあった際に `httpbin.org` という名前のサービスを利用してHTTPリクエストを行い、結果をjsonとして返却しています。基本的には `createRequest` でリクエストを作成し、`parseResponse` でテキストをオブジェクトに変換して利用します。他の関数については後ほど説明します。（[関数についてのヘルプ](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/DWAPI/scriptapi/html/api/class_dw_svc_ServiceCallback.html)）


```js:HttpTest.js
"use strict";

var server = require("server");
var LocalServiceRegistry = require("dw/svc/LocalServiceRegistry");

function createService() {
    return LocalServiceRegistry.createService("httpbin.org", {
        createRequest: function (service, body) {
            var url = service.getURL() + '/anything';
            service.setURL(url)
                .setRequestMethod("POST")
                .addHeader("Content-Type", "application/json");
            return JSON.stringify(body);
        },
        parseResponse: function (service, response) {
            return JSON.parse(response.text);
        },
        mockFull: function () {
            return {
                "test": "モックです"
            }
        },
        getRequestLogMessage: function (request) {
            return JSON.stringify(request) + '---getRequestLogMessage テスト---';
        },
        getResponseLogMessage: function (response) {
            return JSON.stringify(response.getText()) + '---getRequestLogMessage テスト---';
        },
        filterLogMessage: function (msg) {
            return msg + '---filterLogMessage テスト---';
        }
    });
}

server.get("Show", function (req, res, next) {
    var service = createService()
    var result = service.call({
        "test": "テスト"
    })
    res.json(result.object);
    next();
});

module.exports = server.exports();
```




## モック

下記のようにサービスのモードをモックに設定すると外部の接続することなく上記のコード内の `mockFull` で返される値を擬似的に利用することができます。
![スクリーンショット 2023-03-30 15.15.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/ffb10d71-71e1-513a-7430-1e534991df40.png)


今回のコードでモックモードにした場合の結果は下記のようになります。
![スクリーンショット 2023-03-30 15.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/9a985b6f-ab2f-ee51-d8c2-ff26b8d0acac.png)




## ログの出力

下記のようにサービスに対して「通信ログを有効化」することでログを出力することができます。
![スクリーンショット 2023-03-30 15.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/5cce9a9a-7770-76a1-26c8-011cde1d2ac4.png)




また、上記のコードの `filterLogMessage`、`getResponseLogMessage`、`getRequestLogMessage` を利用することで下記のようにログを加工することも可能です。
![スクリーンショット 2023-03-30 15.10.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/98de338c-4d81-4edb-5995-edd56d4d4f58.png)



## 他の認証やプロトコルのサンプル

* FTP
    * [Salesforce B2C Commerce の SFRA にてジョブを利用して SFTP で AWS S3 にファイルアップロードしてみる](https://qiita.com/syunyama/items/bab475237120d927e359)
* OAuth
    * [Salesforce B2C Commerce でOAuthを利用してGoogle Calendar API呼んでみた](https://qiita.com/syunyama/items/c3f5723b41e7e017e32d)



## リソース

* [Web Services](https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/web_services/b2c_webservices.html?resultof=%22%63%72%65%61%74%65%53%65%72%76%69%63%65%22%20%22%63%72%65%61%74%65%73%65%72%76%69%63%65%22%20)