关于 b2c-custom-objects
面向 Salesforce B2C Commerce 开发者的自定义对象技术参考,用于管理标准对象之外的业务数据。内容涵盖对象作用域,以及通过 Script API、OCAPI 和 SCAPI 执行增删改查、查询和购物者只读访问。
主要功能
- 01站点与组织级作用域
- 02Script API 增删改查
- 03OCAPI 数据与搜索端点
- 04通过 SCAPI 提供购物者只读访问
- 05自定义对象查询模式
适用场景
- 01存储站点或全局配置
- 02缓存外部集成数据
- 03建模忠诚度等级或供应商数据
- 04暂存导入数据或作业队列
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ salesforcecommercecloud/ b2c-developer-tooling --skill b2c-custom-objects安装后在 Claude Code 中输入/b2c-custom-objects确认已加载。
附带文件evals/trigger-evals.jsonreferences/OCAPI-SEARCH.md
详细介绍
B2C 自定义对象
自定义对象用于存储不适合放入标准系统对象的业务数据。它们支持站点范围和组织范围(全局)数据,并可通过 Script API 和 OCAPI 执行完整的 CRUD 操作。
何时使用自定义对象
| 用例 | 示例 |
|---|---|
| 业务配置 | 按站点或全局存储配置 |
| 集成数据 | 缓存外部系统的响应 |
| 自定义实体 | 忠诚度等级、自定义促销、供应商数据 |
| 临时处理 | 作业处理队列、导入暂存区 |
自定义对象类型
自定义对象在 Business Manager 的 Administration > Site Development > Custom Object Types 下定义。每种类型都包含:
- ID:唯一标识符(例如,
CustomConfig) - 键属性:用于查找的主键字段
- 属性:用于存储数据的自定义属性
- 范围:站点范围或组织范围(全局)
Script API(CustomObjectMgr)
获取自定义对象
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
// Get a single custom object by type and key
var config = CustomObjectMgr.getCustomObject('CustomConfig', 'myConfigKey');
if (config) {
var value = config.custom.configValue;
}
创建自定义对象
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Transaction = require('dw/system/Transaction');
Transaction.wrap(function() {
// Create new custom object (type, keyValue)
var obj = CustomObjectMgr.createCustomObject('CustomConfig', 'newKey');
obj.custom.configValue = 'myValue';
obj.custom.isActive = true;
});
查询自定义对象
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
// Query with attribute filter
var objects = CustomObjectMgr.queryCustomObjects(
'CustomConfig', // Type
'custom.isActive = {0}', // Query (uses positional params)
'creationDate desc', // Sort order
true // Parameter value for {0}
);
while (objects.hasNext()) {
var obj = objects.next();
// Process object
}
objects.close();
删除自定义对象
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Transaction = require('dw/system/Transaction');
Transaction.wrap(function() {
var obj = CustomObjectMgr.getCustomObject('CustomConfig', 'keyToDelete');
if (obj) {
CustomObjectMgr.remove(obj);
}
});
获取某类型的所有对象
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
// Get all objects of a type
var allConfigs = CustomObjectMgr.getAllCustomObjects('CustomConfig');
while (allConfigs.hasNext()) {
var config = allConfigs.next();
// Process
}
allConfigs.close();
CustomObjectMgr API 参考
| 方法 | 描述 |
|---|---|
getCustomObject(type, keyValue) | 按类型和键获取单个对象 |
createCustomObject(type, keyValue) | 创建新对象(需在事务中执行) |
remove(object) | 删除对象(需在事务中执行) |
queryCustomObjects(type, query, sortString, ...args) | 使用筛选条件进行查询 |
getAllCustomObjects(type) | 获取某类型的所有对象 |
describe(type) | 获取自定义对象类型的元数据 |
OCAPI Data API
获取自定义对象
GET /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}
**注意:**对于站点范围的对象,请使用 /s/{site_id}/dw/data/v25_6/custom_objects/...;对于组织范围(全局)的对象,请使用 /s/-/dw/data/v25_6/custom_objects/...。
创建自定义对象
PUT /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}
Content-Type: application/json
{
"key_property": "myKey",
"c_configValue": "myValue",
"c_isActive": true
}
更新自定义对象
PATCH /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}
Content-Type: application/json
{
"c_configValue": "updatedValue"
}
删除自定义对象
DELETE /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}
搜索自定义对象
POST /s/-/dw/data/v25_6/custom_objects_search/{object_type}
Authorization: Bearer {token}
Content-Type: application/json
{
"query": {
"bool_query": {
"must": [
{ "term_query": { "fields": ["c_isActive"], "operator": "is", "values": [true] } }
]
}
},
"select": "(**)",
"sorts": [{ "field": "creation_date", "sort_order": "desc" }],
"start": 0,
"count": 25
}
搜索查询类型
| 查询类型 | 描述 | 示例 |
|---|---|---|
term_query | 精确匹配/比较 | {"fields": ["c_status"], "operator": "is", "values": ["active"]} |
text_query | 全文搜索 | {"fields": ["c_name"], "search_phrase": "test"} |
filtered_query | 查询加筛选条件——范围查询请与 range_filter 搭配使用 | {"query": {"match_all_query": {}}, "filter": {"range_filter":{"field": "c_count", "from": 1, "to": 10}}} |
bool_query | 组合查询 | {"must": [...], "should": [...], "must_not": [...]} |
match_all_query | 匹配所有记录 | {} |
Shopper Custom Objects API(SCAPI)
如需从店面进行只读访问,请使用 Shopper Custom Objects API。此 API 需要特定的 OAuth 作用域。
获取自定义对象(Shopper)
GET https://{shortCode}.api.commercecloud.salesforce.com/custom-object/shopper-custom-objects/v1/organizations/{organizationId}/custom-objects/{objectType}/{key}?siteId={siteId}
Authorization: Bearer {shopper_token}
所需作用域
对于 Shopper Custom Objects API,请在 SLAS 客户端中配置以下作用域:
sfcc.shopper-custom-objects- 对所有自定义对象类型的全局读取权限sfcc.shopper-custom-objects.{objectType}- 对特定类型的读取权限
**注意:**SLAS 客户端最多可配置 20 个自定义对象作用域。
还必须在 Business Manager 中启用自定义对象类型的 Shopper 访问权限。
可搜索的系统字段
所有自定义对象都提供以下系统字段,可用于 OCAPI 搜索查询:
creation_date- 对象的创建时间(Date)last_modified- 对象的上次修改时间(Date)key_value_string- 字符串键值key_value_integer- 整数键值site_id- 站点标识符(用于站点范围的对象)
最佳实践
应当
- 对创建/更新/删除操作使用事务
- 使用完毕后关闭查询迭代器(
objects.close()) - 使用有意义的键值,以便高效查找
- 为频繁查询的属性创建索引
- 对特定站点的数据使用站点范围的对象
- 对共享配置使用组织范围的对象
不要
- 不加密存储敏感数据
- 创建过多自定义对象类型
- 将自定义对象用于高容量事务数据
- 忘记处理
getCustomObject()返回null的情况 - 保持查询迭代器处于打开状态(会导致资源泄漏)
常见模式
配置存储
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Site = require('dw/system/Site');
function getConfig(key, defaultValue) {
var configKey = Site.current.ID + '_' + key;
var obj = CustomObjectMgr.getCustomObject('SiteConfig', configKey);
if (obj && obj.custom.value !== null) {
return JSON.parse(obj.custom.value);
}
return defaultValue;
}
function setConfig(key, value) {
var Transaction = require('dw/system/Transaction');
var configKey = Site.current.ID + '_' + key;
Transaction.wrap(function() {
var obj = CustomObjectMgr.getCustomObject('SiteConfig', configKey);
if (!obj) {
obj = CustomObjectMgr.createCustomObject('SiteConfig', configKey);
}
obj.custom.value = JSON.stringify(value);
});
}
处理队列
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Transaction = require('dw/system/Transaction');
// Add to queue
function enqueue(data) {
var key = 'job_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
Transaction.wrap(function() {
var obj = CustomObjectMgr.createCustomObject('JobQueue', key);
obj.custom.data = JSON.stringify(data);
obj.custom.status = 'pending';
});
}
// Process queue
function processQueue() {
var pending = CustomObjectMgr.queryCustomObjects(
'JobQueue',
'custom.status = {0}',
'creationDate asc',
'pending'
);
while (pending.hasNext()) {
var job = pending.next();
Transaction.wrap(function() {
job.custom.status = 'processing';
});
try {
var data = JSON.parse(job.custom.data);
processJob(data);
Transaction.wrap(function() {
CustomObjectMgr.remove(job);
});
} catch (e) {
Transaction.wrap(function() {
job.custom.status = 'failed';
job.custom.error = e.message;
});
}
}
pending.close();
}
详细参考
- OCAPI 搜索查询 - 完整的搜索查询语法和示例