mcpField
B
b2c-custom-caches

b2c-custom-caches

github.com/salesforcecommercecloud開発5791 回インストール今日更新
リポジトリ

b2c-custom-caches について

b2c-custom-caches は、Salesforce B2C Commerce でアプリケーションレベルのキャッシュを実装する開発者向けのスキルです。JSON 定義と Script API の使い方に加え、ローダーによる登録、キーのスコープ、有効期限、制限を説明します。

主な機能

  1. 01JSON ファイルでのキャッシュ定義
  2. 02Script API によるキャッシュ利用
  3. 03ローダー関数でのエントリ登録
  4. 04サイトやカタログ単位のキー設定
  5. 05有効期限と無効化の設定

活用シーン

  1. 01外部 API レスポンスのキャッシュ
  2. 02高コストな計算の重複回避
  3. 03頻繁に使う商品データの再利用
  4. 04サイト別設定のキャッシュ

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill b2c-custom-caches

インストール後、Claude Code で/b2c-custom-cachesを入力して読み込まれたか確認します。

同梱ファイルevals/trigger-evals.json

詳細

B2C カスタムキャッシュ

カスタムキャッシュは、計算コストが高いデータ、取得に時間がかかるデータ、または頻繁にアクセスされるデータを保存することで、コードのパフォーマンスを向上させます。キャッシュはカートリッジ内の JSON ファイルで定義し、Script API 経由でアクセスします。

カスタムキャッシュを使用する場面

ユースケース例
計算コストの高い処理ベース商品の表示にあたり、バリエーション商品のいずれかがセール中かどうかを確認する
外部システムからの応答外部 API から取得した店舗在庫や価格をキャッシュする
設定JSON ファイルまたは外部ソースから取得した設定データを保存する
頻繁にアクセスされるデータ商品属性、カテゴリーのデータ、サイトの環境設定

制限事項

制約値
アプリケーションサーバーごとの合計メモリすべてのカスタムキャッシュで約 20 MB
コードバージョンごとの最大キャッシュ数100
エントリーの最大サイズ128 KB
サポートされる値の型プリミティブ、配列、プレーンオブジェクト、null(undefined は不可)
サーバー間の同期なし(キャッシュはアプリケーションサーバーごと)

カスタムキャッシュの定義

ファイル構成
my_cartridge/
├── package.json       # References caches.json
└── caches.json        # Cache definitions
package.json

キャッシュ定義ファイルを指定する caches エントリーを追加します。

{
  "name": "my_cartridge",
  "caches": "./caches.json"
}
caches.json

一意の ID と任意の有効期限を指定してキャッシュを定義します。

{
  "caches": [
    {
      "id": "ProductAttributeCache"
    },
    {
      "id": "ExternalPriceCache",
      "expireAfterSeconds": 300
    },
    {
      "id": "SiteConfigCache",
      "expireAfterSeconds": 60
    }
  ]
}
プロパティ必須説明
idはいコードバージョン内のすべてのカートリッジで一意の ID
expireAfterSecondsいいえエントリーを保持する最大秒数

カスタムキャッシュの使用

Script API クラス
クラス説明
dw.system.CacheMgr定義済みキャッシュにアクセスするためのエントリーポイント
dw.system.Cacheエントリーの保存と取得に使用するキャッシュインスタンス
基本的な使い方
var CacheMgr = require('dw/system/CacheMgr');

// Get a defined cache
var cache = CacheMgr.getCache('ProductAttributeCache');

// Get value (returns undefined if not found)
var value = cache.get('myKey');

// Store value directly
cache.put('myKey', { data: 'value' });

// Remove entry
cache.invalidate('myKey');
推奨パターン:ローダーを使った get

get(key, loader) を使うと、キャッシュミス時にキャッシュへ自動的に値を登録できます。

var CacheMgr = require('dw/system/CacheMgr');
var Site = require('dw/system/Site');

var cache = CacheMgr.getCache('SiteConfigCache');

// Loader function called only on cache miss
var config = cache.get(Site.current.ID + '_config', function() {
    // Expensive operation - only runs if not cached
    return loadConfigurationFromFile(Site.current);
});
スコープ付きキャッシュキー

キーにスコープ識別子を含め、コンテキストごとにエントリーを分けます。

var CacheMgr = require('dw/system/CacheMgr');
var Site = require('dw/system/Site');

var cache = CacheMgr.getCache('ProductCache');

// Site-scoped key
var siteKey = Site.current.ID + '_' + productID;
var productData = cache.get(siteKey, loadProductData);

// Catalog-scoped key
var catalogKey = 'catalog_' + catalogID + '_' + productID;
var catalogData = cache.get(catalogKey, loadCatalogData);

// Locale-scoped key
var localeKey = request.locale + '_' + contentID;
var content = cache.get(localeKey, loadLocalizedContent);

キャッシュメソッド

メソッド説明
get(key)キャッシュされた値、または undefined を返します
get(key, loader)キャッシュされた値を返すか、ローダーを呼び出して結果を保存します
put(key, value)値を直接保存します(既存の値は上書きされます)
invalidate(key)キーに対応するエントリーを削除します

ベストプラクティス

推奨事項
  • 自動登録には get(key, loader) パターンを使用します
  • キャッシュキーにスコープ(サイト、カタログ、ロケール)を含めます
  • 時間の経過で変化するデータには適切な expireAfterSeconds を設定します
  • キャッシュミスを適切に処理します(データはいつでも削除される可能性があります)
  • わかりやすいキャッシュ ID を使用します
避けるべき事項
  • 個人ユーザーデータをキャッシュキーに含めないでください(キーがログに記録される可能性があります)
  • Script API オブジェクトを保存しないでください(プリミティブとプレーンオブジェクトのみ使用してください)
  • キャッシュエントリーが存在することを前提にしないでください(永続性は保証されません)
  • サーバー間でキャッシュが同期されることを期待しないでください
  • undefined の値を保存しないでください(代わりに null を使用します)

キャッシュの無効化

キャッシュは次の場合に自動的にクリアされます。

  • アクティブなコードバージョン内のファイルが変更された場合
  • 新しいコードバージョンが有効化された場合
  • データレプリケーションが完了した場合
  • コードレプリケーションが完了した場合

手動での無効化は、現在のアプリケーションサーバーにのみ適用されます。

var cache = CacheMgr.getCache('MyCache');

// Invalidate single entry (current app server only)
cache.invalidate('myKey');

// Storing undefined has same effect as invalidate
cache.put('myKey', undefined);

よくあるパターン

外部 API 応答のキャッシュ
var CacheMgr = require('dw/system/CacheMgr');
var LocalServiceRegistry = require('dw/svc/LocalServiceRegistry');

var priceCache = CacheMgr.getCache('ExternalPriceCache');

function getExternalPrice(productID) {
    return priceCache.get('price_' + productID, function() {
        var service = LocalServiceRegistry.createService('PriceService', {
            createRequest: function(svc, args) {
                svc.setRequestMethod('GET');
                svc.addParam('productId', args.productID);
                return null;
            },
            parseResponse: function(svc, response) {
                return JSON.parse(response.text);
            }
        });

        var result = service.call({ productID: productID });
        return result.ok ? result.object : null;
    });
}
計算コストの高い処理のキャッシュ
var CacheMgr = require('dw/system/CacheMgr');

var saleCache = CacheMgr.getCache('ProductSaleCache');

function isProductOnSale(masterProduct) {
    return saleCache.get('sale_' + masterProduct.ID, function() {
        var variants = masterProduct.variants.iterator();
        while (variants.hasNext()) {
            var variant = variants.next();
            if (isInPromotion(variant)) {
                return true;
            }
        }
        return false;
    });
}
サイトスコープを指定した設定キャッシュ
var CacheMgr = require('dw/system/CacheMgr');
var Site = require('dw/system/Site');
var File = require('dw/io/File');
var FileReader = require('dw/io/FileReader');

var configCache = CacheMgr.getCache('SiteConfigCache');

function getSiteConfig() {
    var siteID = Site.current.ID;

    return configCache.get(siteID + '_config', function() {
        var configFile = new File(File.IMPEX + '/src/config/' + siteID + '.json');
        if (!configFile.exists()) {
            return null;
        }

        var reader = new FileReader(configFile);
        var content = reader.getString();
        reader.close();

        return JSON.parse(content);
    });
}

トラブルシューティング

問題原因解決方法
キャッシュが見つからない例外どの caches.json にもキャッシュ ID が定義されていないcaches.json にキャッシュ定義を追加します
キャッシュ ID の重複エラー複数のカートリッジで同じ ID が使用されているすべてのカートリッジで一意の ID を使用します
エントリーが保存されない値が 128 KB の上限を超えているデータサイズを小さくするか、データの一部だけをキャッシュします
エントリーが保存されない値に Script API オブジェクトが含まれているプリミティブとプレーンオブジェクトのみ使用します
キャッシュミスが予期せず発生する別のアプリケーションサーバーを使用しているか、キャッシュがクリアされた常にキャッシュミスを適切に処理します

キャッシュ関連のメッセージについては、カスタムエラーログとカスタム警告ログを確認してください。

コメント