关于 b2c-webservices
面向 Salesforce B2C Commerce 开发者的 Web Services 技能,指导使用 Service Framework 集成外部服务。内容涵盖服务配置、回调、错误处理、日志过滤与模拟测试。
主要功能
- 01配置 HTTP、SOAP 和文件传输服务
- 02使用 LocalServiceRegistry 创建服务
- 03实现请求与响应回调
- 04处理限流和断路器
- 05过滤日志敏感信息并模拟调用
适用场景
- 01连接外部 REST API 或 SOAP 服务
- 02通过 FTP 或 SFTP 传输文件
- 03为服务调用设置超时和限流
- 04在不调用外部系统时测试集成
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ salesforcecommercecloud/ b2c-developer-tooling --skill b2c-webservices安装后在 Claude Code 中输入/b2c-webservices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/trigger-evals.jsonreferences/FTP-SERVICES.mdHTTP-SERVICES.mdSERVICES-XML.mdSOAP-SERVICES.md详细介绍
Web Services 技能
此技能将指导你使用 Service Framework 在 B2C Commerce 中实现 Web 服务集成。
概述
Service Framework 提供了一种结构化方式来调用外部服务,具备以下功能:
| 功能 | 描述 |
|---|---|
| 配置 | 在 Business Manager 中管理服务设置 |
| 速率限制 | 自动限制调用频率,保护外部系统 |
| 熔断器 | 自动处理故障,防止故障级联 |
| 日志记录 | 记录通信日志并过滤敏感数据 |
| 模拟 | 无需调用外部服务即可测试服务 |
服务类型
| 类型 | 用例 | 协议 |
|---|---|---|
HTTP | REST API、Webhook | HTTP/HTTPS |
HTTPForm | 表单提交 | 使用表单编码的 HTTP/HTTPS |
FTP | 文件传输(已弃用) | FTP |
SFTP | 安全文件传输 | SFTP |
SOAP | SOAP Web 服务 | 使用 SOAP 的 HTTP/HTTPS |
GENERIC | 自定义协议 | 任意 |
Service Framework 组件
Business Manager 配置
服务在 Administration > Operations > Services 中配置:
- Service Configuration - 常规设置(启用状态、日志记录、回调)
- Service Profile - 速率限制和熔断器设置
- Service Credential - URL 和身份验证凭据
脚本组件
| 组件 | 用途 |
|---|---|
LocalServiceRegistry | 创建服务实例 |
ServiceCallback | 定义请求/响应处理方式 |
Service | 提供通用方法的基础服务 |
Result | 包含状态和数据的响应对象 |
基本模式
'use strict';
var LocalServiceRegistry = require('dw/svc/LocalServiceRegistry');
var myService = LocalServiceRegistry.createService('my.service.id', {
/**
* Configure the request before it is sent
* @param {dw.svc.HTTPService} svc - The service instance
* @param {Object} params - Parameters passed to service.call()
* @returns {string} Request body
*/
createRequest: function (svc, params) {
svc.setRequestMethod('POST');
svc.addHeader('Content-Type', 'application/json');
return JSON.stringify(params);
},
/**
* Parse the response after a successful call
* @param {dw.svc.HTTPService} svc - The service instance
* @param {dw.net.HTTPClient} client - The HTTP client with response
* @returns {Object} Parsed response
*/
parseResponse: function (svc, client) {
return JSON.parse(client.text);
},
/**
* Filter sensitive data from logs (required for production)
* @param {string} msg - The message to filter
* @returns {string} Filtered message
*/
filterLogMessage: function (msg) {
return msg.replace(/("api_key"\s*:\s*")[^"]+"/g, '$1***"');
}
});
// Call the service
var result = myService.call({ key: 'value' });
if (result.ok) {
var data = result.object;
} else {
var error = result.errorMessage;
}
服务回调
| 回调 | 必需 | 描述 |
|---|---|---|
createRequest | 是* | 配置请求并返回正文 |
parseResponse | 是* | 解析响应并返回结果对象 |
execute | 否 | 自定义执行逻辑(替代默认逻辑) |
initServiceClient | 否 | 创建/配置底层客户端 |
mockCall | 否 | 返回模拟响应(仅执行阶段) |
mockFull | 否 | 返回模拟响应(整个调用过程) |
filterLogMessage | 建议使用 | 从日志中过滤敏感数据 |
getRequestLogMessage | 否 | 自定义请求日志消息 |
getResponseLogMessage | 否 | 自定义响应日志消息 |
*除非实现了 execute,否则为必需
Result 对象
call() 方法返回一个 dw.svc.Result:
| 属性 | 类型 | 描述 |
|---|---|---|
ok | Boolean | 成功时为 True |
status | String | "OK"、"ERROR" 或 "SERVICE_UNAVAILABLE" |
object | Object | parseResponse 返回的响应 |
error | Number | 错误代码(例如 HTTP 状态码) |
errorMessage | String | 错误描述 |
unavailableReason | String | 服务不可用的原因 |
mockResult | Boolean | 来自模拟回调时为 True |
不可用原因
| 原因 | 描述 |
|---|---|
TIMEOUT | 调用超时 |
RATE_LIMITED | 超出速率限制 |
CIRCUIT_BROKEN | 熔断器已打开 |
DISABLED | 服务已禁用 |
CONFIG_PROBLEM | 配置错误 |
错误处理
var result = myService.call(params);
if (result.ok) {
return result.object;
}
// Handle different error types
switch (result.status) {
case 'SERVICE_UNAVAILABLE':
switch (result.unavailableReason) {
case 'RATE_LIMITED':
// Retry later
break;
case 'CIRCUIT_BROKEN':
// Service is down, use fallback
break;
case 'TIMEOUT':
// Request timed out
break;
}
break;
case 'ERROR':
// Check HTTP status code
if (result.error === 401) {
// Authentication error
} else if (result.error === 404) {
// Resource not found
}
break;
}
throw new Error('Service error: ' + result.errorMessage);
日志过滤
生产环境需要进行日志过滤,以防止敏感数据泄露:
var myService = LocalServiceRegistry.createService('my.service', {
createRequest: function (svc, params) {
// ... configure request
},
parseResponse: function (svc, client) {
return JSON.parse(client.text);
},
/**
* Filter sensitive data from all log messages
*/
filterLogMessage: function (msg) {
// Filter API keys
msg = msg.replace(/api_key=[^&]+/g, 'api_key=***');
// Filter authorization headers
msg = msg.replace(/Authorization:\s*[^\r\n]+/gi, 'Authorization: ***');
// Filter passwords in JSON
msg = msg.replace(/("password"\s*:\s*")[^"]+"/g, '$1***"');
return msg;
},
/**
* Custom request log message (optional)
*/
getRequestLogMessage: function (request) {
// Return custom message or null for default
return 'Request: ' + request.substring(0, 100) + '...';
},
/**
* Custom response log message (optional)
*/
getResponseLogMessage: function (response) {
// Return custom message or null for default
return 'Response received';
}
});
模拟服务
使用模拟回调进行测试,无需调用外部服务:
var myService = LocalServiceRegistry.createService('my.service', {
createRequest: function (svc, params) {
svc.setRequestMethod('GET');
svc.addParam('id', params.id);
return null;
},
parseResponse: function (svc, client) {
return JSON.parse(client.text);
},
/**
* Mock the execute phase only (createRequest and parseResponse still run)
*/
mockCall: function (svc, request) {
return {
statusCode: 200,
text: JSON.stringify({ id: 1, name: 'Mock Data' })
};
},
/**
* Or mock the entire call (replaces all phases)
*/
mockFull: function (svc, params) {
return { id: params.id, name: 'Full Mock Data' };
}
});
// Force mock mode
myService.setMock();
var result = myService.call({ id: 123 });
在 Business Manager 中配置服务
创建服务
- 前往 Administration > Operations > Services
- 在 Service Configurations 下点击 New
- 填写:
- Service ID:唯一标识符(例如
my.api.service) - Service Type:HTTP、FTP、SOAP 等
- Enabled:勾选以启用
- Profile:选择或创建配置文件
- Credential:选择或创建凭据
- Communication Log:启用以便调试
- Service ID:唯一标识符(例如
服务配置文件设置
| 设置 | 说明 |
|---|---|
| 超时 | 最大等待时间,单位为毫秒 |
| 速率限制 | 每个时间单位内的最大调用次数 |
| 启用熔断器 | 启用自动故障处理 |
| 熔断器最大调用次数 | 熔断器开启前的调用次数 |
| 熔断器间隔 | 用于跟踪故障的时间窗口 |
服务凭证设置
| 设置 | 说明 |
|---|---|
| ID | 凭证标识符 |
| URL | 服务的基础 URL |
| 用户 | 用于身份验证的用户名 |
| 密码 | 用于身份验证的密码 |
详细参考
- HTTP 服务 - REST API 集成
- FTP/SFTP 服务 - 文件传输操作
- SOAP 服务 - SOAP Web 服务集成
- 服务 XML - 导入/导出服务配置
脚本 API 类
| 类 | 说明 |
|---|---|
dw.svc.LocalServiceRegistry | 创建服务实例 |
dw.svc.Service | 服务基类 |
dw.svc.HTTPService | HTTP 服务方法 |
dw.svc.FTPService | FTP/SFTP 服务方法 |
dw.svc.SOAPService | SOAP 服务方法 |
dw.svc.Result | 服务调用结果 |
dw.svc.ServiceConfig | 服务配置 |
dw.svc.ServiceProfile | 速率限制/熔断器配置 |
dw.svc.ServiceCredential | 身份验证凭证 |
dw.net.HTTPClient | 底层 HTTP 客户端 |
dw.net.FTPClient | 底层 FTP 客户端 |
dw.net.SFTPClient | 底层 SFTP 客户端 |
评论
支持 Markdown