カスタム API

B2C Commerce には、買い物客の体験をカスタマイズするための強力なツールが用意されています。現在、SCAPI はフックを使用してカスタマイズでき、デベロッパーは B2C Commerce Script API を使用してフィルターを追加したり、レスポンスを変更したりしてから、呼び出し元のアプリケーションに送り返すことができます。

既存の開発ツールをさらに活用するために、デベロッパーがコントローラーなどのカスタムスクリプトコードを記述し、この機能を SCAPI フレームワークの下でカスタム REST API として公開できるフレームワークを提供します。

SCAPI カスタム API のビデオでは、カスタム API を使用してカートリッジを作成する方法を順を追って説明しています。ビデオで提供されているコードサンプルにアクセスできない場合は、Salesforce Commerce Cloud GitHub リポジトリとアクセスを参照してください。

SCAPI Custom APIs

概要 

カスタム API URL の構造形式は次のとおりです。

https://{shortCode}.api.commercecloud.salesforce.com/custom/{apiName}/{apiVersion}/organizations/{organizationId}/{endpointPath}

custom という用語は API ファミリーとして使用する必要があります。パラメーター apiName、apiVersion、および endpointPath は、以下で説明するように定義できます。

カスタム API を作成するには、次の 3 つのコンポーネントが必須です。

  • OAS 3.0スキーマファイルとしての API コントラクト。
  • B2C Commerce Script API を使用したスクリプトとしての API 実装。
  • api.jsonファイルで定義される ** API マッピング**。

このガイドでは、特定の顧客のロイヤルティステータスを取得するために使用できる Loyalty Info API という例を見ていきます。以下の図は、必要なコンポーネントとその関係を示しています。

カスタム API と B2C Commerce プラットフォームの統合

このページ内のリンクには、既存のお客様のみがアクセスできるものがあります。Commerce Cloud リポジトリにアクセスする方法については Salesforce Commerce Cloud GitHub リポジトリとアクセスを参照してください。

Tip

コンポーネントについては、次のセクションで詳しく説明します。今のところ、図に関する次の詳細に注意してください。

  • 破線は、この URL セグメントが定義されている場所を示しています。
  • 青色のパラメーターはエンドポイント識別子です。これは、エンドポイントを実装にバインドするために使用され、3 つのコンポーネントすべてに表示されます。

カートリッジ 

カスタム API はカスタムコードカートリッジ内で定義されます。cartridge ディレクトリに、そのカートリッジ内のすべての API のルートフォルダーである rest-apis という新規フォルダーを作成する必要があります。

rest-apis フォルダーのサブディレクトリは、実際の API を表します。これらのディレクトリ名は、URL によってアドレス指定される API 名を表します。各ディレクトリには、この API を表す 3 つのコンポーネントのファイルが含まれています。

例: loyalty-info と呼ばれるサンプル API の構造は、次のようになります。

Cartridge structure
1/my-cartridge
2    /cartridge
3        package.json
4        /rest-apis
5            /loyalty-info
6                api.json
7                schema.yaml
8                schema_v2.yaml
9                script.js
10                script_v2.js
11        /pipelines
12        /scripts
13        /controllers

API ディレクトリ名に使用できるのは、英数字、小文字、ハイフンのみです。

Important

登録プロセスのため、新しいコードのバージョンでカスタム API エンドポイントの実装を開始することをおすすめします。

Tip

コントラクト 

API コントラクトは、YAML 形式の OAS 3.0 スキーマファイルによって提供する必要があります。OAS 3.0 について詳しくは、OAS 3.0 仕様を参照してください。

このスキーマファイルでは、API バージョンと エンドポイント が定義されます。API バージョンは info.version フィールドにあり、メジャーバージョンのセグメントを使用して先頭に v を追加することで URL バージョンに変換されます (例: 1.0.1 → v1)。

エンドポイントは paths オブジェクトの一部として定義され、複数の操作 (HTTP メソッドなど) を実装できます。各操作には operationId というプロパティが必要です。これはスキーマファイル内で一意である 必要 があります。このプロパティはエンドポイントを実装にマッピングするために使用されます。エンドポイントの path は、URL 構造の endpointPath になります。

エンドポイントを保護するには、共有コンポーネントで有効なセキュリティスキームを定義し、エンドポイントまたはグローバルレベルで適用する必要があります。詳細については、認証を参照してください。

例: バージョン v1 の /customers?c_customer_id={id} エンドポイントのスキーマは、次のようになると予想されます。

schema.yaml:
1openapi: 3.0.0
2info:
3  version: 1.0.1
4  title: Loyalty Information API
5components:
6  securitySchemes:
7    ShopperToken:
8      type: oauth2
9      flows:
10        authorizationCode:
11          authorizationUrl: https://my-shortcode.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/my-org-id/oauth2/authorize
12          tokenUrl: https://my-shortcode.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/my-org-id/oauth2/token
13          scopes:
14            c_loyaltyInfo_r: Read loyalty information of a customer
15        clientCredentials:
16          tokenUrl: https://my-shortcode.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/my-org-id/oauth2/token
17          scopes:
18            c_loyaltyInfo_r: Read loyalty information of a customer
19paths:
20  /customers:
21    get:
22      summary: Get loyalty information for customer
23      operationId: getLoyaltyInfo
24      parameters:
25        - in: query
26          name: c_customer_id
27          required: true
28          schema:
29            type: string
30        - in: query
31          name: siteId
32          required: true
33          schema:
34            type: string
35            minLength: 1
36        - in: query
37          name: locale
38          required: false
39          schema:
40            type: string
41            minLength: 1
42      responses:
43        "200":
44          description: Shows loyalty information for the customer
45          content:
46            application/json:
47              schema:
48                type: object
49                properties:
50                  tier:
51                    type: string
52                  points:
53                    type: integer
54        "404":
55          description: Shows that the customer is not found
56          content:
57            application/json:
58              examples:
59                not_found:
60                  value:
61                    {
62                      "type": "https://api.commercecloud.salesforce.com/documentation/error/v1/custom-errors/customer-not-found",
63                    }
64security:
65  - ShopperToken: ["c_loyaltyInfo_r"]

実装 

API 実装は、B2C Commerce Script API を使用するスクリプトファイルによって提供されます。機能名は、コントラクト内のエンドポイントの operationId の値と一致する 必要があり ます。

例: コントラクトの定義に基づいた /customers?c_customer_id={id} の有効な実装は次のようになります。

script.js:
1var RESTResponseMgr = require("dw/system/RESTResponseMgr");
2
3exports.getLoyaltyInfo = function () {
4
5  var customerId = request
6    .getHttpParameterMap()
7    .get("c_customer_id")
8    .getStringValue();
9
10  /*
11    ... some lookup of loyalty data based on customer id ...
12  */
13
14  if (customerId === "customer1") {
15
16    var info = {
17      tier: "silver",
18      points: 14275
19    };
20
21    RESTResponseMgr
22      .createSuccess(info)
23      .render();
24
25  } else {
26
27    RESTResponseMgr
28      .createError(404, "customer-not-found", "Customer Unknown", "You provided an unknown customer ID.")
29      .render();
30
31  }
32
33};
34
35exports.getLoyaltyInfo.public = true;

レスポンスは、常に JSON 形式で返すことを 強く 推奨します。さらに、エラーは RFC 9457 に記述されている SCAPI エラー形式に準拠し、少なくとも type フィールドが存在する必要があります。レスポンスボディは将来的に検証の対象となり、これらの要件を満たさない場合は拒否される可能性があります。

Important

実装に、十分なエラー処理を備えた高品質で十分にテストされたコードが含まれていることを確認してください。プラットフォームを保護するために、カスタム API は、実装がスローするエラーが多すぎる場合に API リクエストをブロックするサーキットブレーカーメカニズムを使用します。詳細については、サーキットブレーカーを参照してください。

Important

スクリプトで JSON レスポンスを簡単に作成する方法については、Script API クラスの RESTResponseMgr ドキュメントを参照してください。

Tip

マッピング 

API マッピングは、api.json ファイルで提供されます。このファイルにはエンドポイントのリストが含まれており、各エントリに対してエンドポイント名、そのスキーマファイル、および実装スクリプト名が定義されています。

例: コントラクトと実装の定義に基づいた /customers?c_customer_id={id} の有効なマッピングは、次のようになると予想されます。

api.json:
1{
2  "endpoints": [
3    {"endpoint": "getLoyaltyInfo", "schema": "schema.yaml", "implementation": "script"},
4    {"endpoint": "getLoyaltyInfo", "schema": "schema_v2.yaml", "implementation": "script_v2"}
5  ]
6}

相対パスはサポートされていません。スキーマと実装は、対応する api.json と同じレベルに配置する必要があります。

Important

実装名はファイル拡張子を付けずに指定してください。

Important

エンドポイントの登録 

前述のようにカスタム API エンドポイントが正しく定義されたら、アクセスできるように登録する必要があります。

新しい API 定義を含む コードのバージョンを有効化 することによって、登録がトリガーされます。API の変更が必要な場合は、新しいコードのバージョンで作業をし、準備が完了した時点でバージョンを切り替えることを推奨します。

バージョン管理 

カスタム API のバージョンは、API バージョン と URL バージョン という異なる 2 つの形式で表されます。

API バージョンはコントラクト内で info.version フィールドの一部として定義され、このファイルで定義されたすべてのエンドポイントに適用されます。値は数値である必要がありますが、ドットで区切られた複数のセグメントを含めることもできます。

URL では、バージョンはメジャーバージョンのセグメントを使用し、先頭に v を追加することによって変換されます。たとえば、次のリストは有効な API バージョンと、それに対応する URL バージョンを示しています。

  • 1 → v1
  • 1.0 → v1
  • 2.0 → v2
  • 2.1.1 → v2

破壊的変更 (breaking change) は、新規のメジャーバージョンで導入することを推奨します。詳細については、SCAPI の変更ポリシーのセクションを参照してください。

システムクエリパラメーター 

コントラクトで定義されている場合、次のシステムクエリパラメーターは存在し、使用できます。

  • siteId - 現在のリクエストのサイト
  • locale - 現在のリクエストの地域情報

これらのパラメーターの意味と、使用するタイミングを必ず理解してください。たとえば、システムは siteId を使用してサイトのコンテキストを識別するため、このパラメーターの使用は Shopper API リクエストでのみ意味があります。サイトでフィルタリングされたオブジェクトを返す API など、サイトを必要とする Admin API リクエストの場合は、c_siteId などのカスタムクエリパラメーターを使用します。サイトはパスパラメーターではなくクエリパラメーターであり、コントローラーやフックの使用など、他のカスタマイズ方法とは異なることに注意してください。 パラメーター locale は、リクエストの地域情報を設定するために使用され、Script API メソッド dw.system.Request#setLocale と同じように動作します。

siteId が指定されていない場合、リクエストは SCAPI Admin API リクエストとして扱われ、Business Manager サイトが使用されます。リクエストで locale が指定されていない場合は、サイトのデフォルトの地域情報が使用されます。

siteId パラメーターはカスタム API の登録にも使用されます。つまり、カスタム API を含むカートリッジがサイトのカートリッジパスに追加されていない場合、その siteId を使用してリクエストすると、404 レスポンスが返されます。Admin API の場合、カートリッジを Business Manager サイトのカートリッジパスに追加する必要があります。

Note

Admin API リクエストに買い物客トークンを使用することは許可されていません。このようなシナリオでは、AmOAuth2 トークンを使用します。

例 1: siteId の名前とタイプ string を使用してシステムクエリパラメーターを定義します。パラメーターが有効な文字列でない場合、リクエストは拒否されます。

1- in: query
2  name: siteId
3  required: true
4  schema:
5    type: string
6    minLength: 1

例 2: 名前 locale とタイプ string を使用してシステムクエリパラメーターを定義します。パラメーターが有効な文字列でない場合、リクエストは拒否されます。

1- in: query
2  name: locale
3  required: false
4  schema:
5    type: string
6    minLength: 1

例 3: システムクエリパラメーターを使用してカスタム API リクエストを行います。

1GET https://my-shortcode.api.commercecloud.salesforce.com/custom/loyalty-info/v1/organizations/my-org-id/customers?c_customer_id=customer1?siteId=MySite&locale=en-US

システムクエリパラメーターは、前に示したように、正しい schema フィールドで定義する必要があります。required を false に設定すると、この値は必須ではありません。required がtrue されている場合、パラメーターが欠落しているか空の場合、リクエストは拒否されます。

Important

Shopper および Admin API のエンドポイント 

非カスタム B2C Commerce API (SCAPI) と同様に、各エンドポイントは Shopper または Admin API エンドポイントのいずれかです。これらの API グループを区別する方法の一般的な情報については、SCAPI グループを参照してください。

カスタム API の場合、Shopper エンドポイントと Admin エンドポイントには主に 3 つの違いがあります。

  1. Shopper のエンドポイントでは、リクエストランタイム、リクエストボディのサイズ、および API クォータに対してより厳しい制限が設定されています。特定の値については制限事項を参照してください。
  2. Shopper エンドポイントでは siteId クエリパラメーターが必要ですが、Admin エンドポイントではこのパラメーターを省略する必要があります。siteId のないリクエストは、Admin API リクエストとして扱われます。
  3. Shopper エンドポイントには ShopperToken セキュリティスキームが必要であり、Admin エンドポイントには AmOAuth2 セキュリティスキームが必要です。また、各エンドポイントに設定できるセキュリティスキームは 1 つだけです。これらの使用方法については、認証を参照してください。

サポートされている HTTP メソッド 

カスタム API でサポートされているメソッドは次のとおりです。

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
  • HEAD
  • OPTIONS

次の例では、管理者がロイヤルティ情報を更新できる POST メソッドを使用して Loyalty Information API を拡張します。

schema.yaml:
1openapi: 3.0.0
2info:
3  version: 1.0.1
4  title: Loyalty Information API
5components:
6  securitySchemes:
7    AmOAuth2:
8      type: oauth2
9      flows:
10        authorizationCode:
11          authorizationUrl: https://account.demandware.com/dwsso/oauth2/authorize
12          tokenUrl: https://account.demandware.com/dwsso/oauth2/access_token
13          scopes:
14            c_loyaltyInfo_rw: Read or Update loyalty information of a customer
15        clientCredentials:
16          tokenUrl: https://account.demandware.com/dwsso/oauth2/access_token
17          scopes:
18            c_loyaltyInfo_rw: Read or Update loyalty information of a customer
19paths:
20  /customers/{customerId}:
21    post:
22      summary: Update loyalty information for customer
23      operationId: updateLoyaltyInfo
24      parameters:
25        - in: path
26          name: customerId
27          required: true
28          schema:
29            type: string
30      requestBody:
31        content:
32          'application/json':
33            schema:
34              type: object
35              required:
36                - points
37              properties:
38                points:
39                  type: number
40                  minimum: 1
41                  maximum: 99999
42      responses:
43        "200":
44          description: Shows loyalty information for the customer
45          content:
46            application/json:
47              schema:
48                type: object
49                properties:
50                  tier:
51                    type: string
52                  points:
53                    type: integer
54        "404":
55          description: Shows that the customer is not found
56          content:
57            application/json:
58              examples:
59                not_found:
60                  value:
61                    {
62                      "type": "https://api.commercecloud.salesforce.com/documentation/error/v1/custom-errors/customer-not-found",
63                    }
64security:
65  - AmOAuth2: ["c_loyaltyInfo_rw"]

このエンドポイントの実装例を次に示します。

script.js:
1var RESTResponseMgr = require("dw/system/RESTResponseMgr");
2
3exports.updateLoyaltyInfo = function () {
4
5  var customerId = request
6    .getSCAPIPathParameters()
7    .get('customerId');
8
9  var requestBody = request
10    .httpParameterMap
11    .requestBodyAsString;
12  var requestJSON = JSON.parse( requestBody );
13
14  /*
15    ... Update loyalty points based on customer id and request body ...
16  */
17
18
19  if (customerId === "customer1") {
20
21    var updatedInfo = {
22      tier: "silver",
23      points: requestJSON.points
24    };
25
26    RESTResponseMgr
27      .createSuccess(updatedInfo)
28      .render();
29
30  } else {
31
32    RESTResponseMgr
33      .createError(404, "customer-not-found", "Customer Unknown", "You provided an unknown customer ID.")
34      .render();
35
36  }
37
38};
39
40exports.updateLoyaltyInfo.public = true;

SCAPI パス解析のための新しい便利なメソッドの詳細については、Script API の Request クラスを参照してください。

Tip

属性 additionalProperties は、リクエストボディスキーマを定義するときに許可されません。リクエストボディの検証を利用し、堅牢な API を構築するには、リクエストボディスキーマを詳細に定義します。エンドポイントのリクエストボディスキーマに additionalProperties が含まれている場合、エンドポイントは登録されません。

Note

検証 

不明なパラメーターをもつリクエストは拒否されるため、すべてのリクエストパラメーターをコントラクトで定義する 必要があります。カスタムクエリパラメーターには、c_ という接頭辞を付ける必要があります。システムクエリパラメーターを使用する場合は、コントラクトに追加する必要があります。

例: 名前 c_status とタイプ integer を使用して必須のクエリパラメーターを定義します。パラメーターが存在しない、または有効な整数ではない場合、リクエストは拒否されます。

1/error:
2  get:
3    summary: Throw an error
4    operationId: throwError
5    parameters:
6      - in: query
7        name: c_status
8        required: true
9        schema:
10          type: integer

カスタム API コレクションの例 

このリポジトリにアクセスするには、Trail Tools & Resources for Salesforce B2C Commerce Developers (Salesforce B2C Commerce デベロッパー用のツールとリソース) を完了してください。

Tip

当社のコミュニティは、サンプルフックコレクションでカスタム API のコレクションを管理しており、、以前にフックで提供されていた機能を新しいカスタム API として提供しています。このコレクションで使用できる API をいくつか次に示します。

  • URL Resolution (URL 解決)
  • URL List (URL リスト) API
  • Guest Order Look Up (ゲスト注文検索)
  • Customer Groups (顧客グループ) API
  • Mini Product (ミニ商品)
  • Send Mail (メール送信) API
  • Geo IP API

詳細については、Salesforce Commerce Cloud GitHub リポジトリのCustom APIs Collection (カスタム API コレクション) を参照してください。

制限事項 

以下の制限があります。

  • 全般:
    • GET リクエストの場合、トランザクションをコミットできません。
    • スキーマ属性 additionalProperties は使用できません。
    • Shopper API と Admin API は、該当する API クォータに従う必要があります。クォータの詳細については、API クォータのドキュメントを参照してください。
  • Shopper API:
    • リクエストの最大実行時間は 10 秒です。
    • リクエストボディの最大サイズは 5 MiB (5,242,880 バイト) です。
    • STOREFRONT アクティビティタイプ。ストアフロントのクォータ制限が適用されます。
  • SCAPI Admin API:
    • リクエストの最大実行時間は 60 秒です。
    • リクエストボディの最大サイズは 20 MB (20,000,000 バイト) です。
    • BUSINESS_MANAGER アクティビティタイプ。デフォルトのクォータ制限が適用されます。