b2c-webservices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Web Services Skill

Web服务技能

This skill guides you through implementing web service integrations in B2C Commerce using the Service Framework.
本技能将指导你使用Service Framework在B2C Commerce中实现Web服务集成。

Overview

概述

The Service Framework provides a structured way to call external services with:
FeatureDescription
ConfigurationService settings managed in Business Manager
Rate LimitingAutomatic throttling to protect external systems
Circuit BreakerAutomatic failure handling to prevent cascade failures
LoggingCommunication logging with sensitive data filtering
MockingTest services without external calls
Service Framework提供了结构化的外部服务调用方式,具备以下特性:
功能描述
Configuration可在Business Manager中管理服务设置
Rate Limiting自动限流以保护外部系统
Circuit Breaker自动故障处理,防止级联故障
Logging支持通信日志,可自动过滤敏感数据
Mocking无需调用外部服务即可完成服务测试

Service Types

服务类型

TypeUse CaseProtocol
HTTP
REST APIs, webhooksHTTP/HTTPS
HTTPForm
Form submissionsHTTP/HTTPS with form encoding
FTP
File transfers (deprecated)FTP
SFTP
Secure file transfersSFTP
SOAP
SOAP web servicesHTTP/HTTPS with SOAP
GENERIC
Custom protocolsAny
类型使用场景协议
HTTP
REST API、webhook调用HTTP/HTTPS
HTTPForm
表单提交带表单编码的HTTP/HTTPS
FTP
文件传输(已废弃)FTP
SFTP
安全文件传输SFTP
SOAP
SOAP Web服务调用带SOAP的HTTP/HTTPS
GENERIC
自定义协议任意协议

Service Framework Components

Service Framework 组件

Business Manager Configuration

Business Manager 配置

Services are configured in Administration > Operations > Services:
  1. Service Configuration - General settings (enabled, logging, callbacks)
  2. Service Profile - Rate limiting and circuit breaker settings
  3. Service Credential - URL and authentication credentials
服务在 Administration > Operations > Services 路径下配置:
  1. 服务配置 - 通用设置(启用状态、日志、回调)
  2. 服务配置文件 - 限流和circuit breaker设置
  3. 服务凭证 - URL和身份验证凭证

Script Components

脚本组件

ComponentPurpose
LocalServiceRegistry
Creates service instances
ServiceCallback
Defines request/response handling
Service
Base service with common methods
Result
Response object with status and data
组件用途
LocalServiceRegistry
创建服务实例
ServiceCallback
定义请求/响应处理逻辑
Service
包含通用方法的基础服务类
Result
包含状态和数据的响应对象

Basic Pattern

基础模式

javascript
'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;
}
javascript
'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;
}

Service Callbacks

服务回调

CallbackRequiredDescription
createRequest
Yes*Configure request, return body
parseResponse
Yes*Parse response, return result object
execute
NoCustom execution logic (replaces default)
initServiceClient
NoCreate/configure underlying client
mockCall
NoReturn mock response (execute phase only)
mockFull
NoReturn mock response (entire call)
filterLogMessage
RecommendedFilter sensitive data from logs
getRequestLogMessage
NoCustom request log message
getResponseLogMessage
NoCustom response log message
*Required unless
execute
is implemented
回调是否必填描述
createRequest
是*配置请求,返回请求体
parseResponse
是*解析响应,返回结果对象
execute
自定义执行逻辑(替代默认逻辑)
initServiceClient
创建/配置底层客户端
mockCall
返回Mock响应(仅执行阶段生效)
mockFull
返回Mock响应(全调用流程生效)
filterLogMessage
推荐实现过滤日志中的敏感数据
getRequestLogMessage
自定义请求日志内容
getResponseLogMessage
自定义响应日志内容
*除非实现了
execute
,否则必填

Result Object

结果对象

The
call()
method returns a
dw.svc.Result
:
PropertyTypeDescription
ok
BooleanTrue if successful
status
String"OK", "ERROR", or "SERVICE_UNAVAILABLE"
object
ObjectResponse from
parseResponse
error
NumberError code (e.g., HTTP status)
errorMessage
StringError description
unavailableReason
StringWhy service is unavailable
mockResult
BooleanTrue if from mock callback
call()
方法返回
dw.svc.Result
对象:
属性类型描述
ok
布尔值调用成功则为true
status
字符串取值为"OK"、"ERROR"或"SERVICE_UNAVAILABLE"
object
对象
parseResponse
返回的响应内容
error
数字错误码(例如HTTP状态码)
errorMessage
字符串错误描述
unavailableReason
字符串服务不可用的原因
mockResult
布尔值来自Mock回调则为true

Unavailable Reasons

不可用原因

ReasonDescription
TIMEOUT
Call timed out
RATE_LIMITED
Rate limit exceeded
CIRCUIT_BROKEN
Circuit breaker open
DISABLED
Service disabled
CONFIG_PROBLEM
Configuration error
原因描述
TIMEOUT
调用超时
RATE_LIMITED
超过限流阈值
CIRCUIT_BROKEN
Circuit Breaker已打开
DISABLED
服务已禁用
CONFIG_PROBLEM
配置错误

Error Handling

错误处理

javascript
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);
javascript
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);

Log Filtering

日志过滤

Production environments require log filtering to prevent sensitive data exposure:
javascript
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';
    }
});
生产环境需要开启日志过滤,避免敏感数据泄露:
javascript
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';
    }
});

Mocking Services

服务Mock

Use mock callbacks for testing without external calls:
javascript
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 });
可使用Mock回调在不调用外部服务的情况下完成测试:
javascript
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 });

Service Configuration in Business Manager

Business Manager中的服务配置

Creating a Service

创建服务

  1. Go to Administration > Operations > Services
  2. Click New under Service Configurations
  3. Fill in:
    • Service ID: Unique identifier (e.g.,
      my.api.service
      )
    • Service Type: HTTP, FTP, SOAP, etc.
    • Enabled: Check to enable
    • Profile: Select or create a profile
    • Credential: Select or create credentials
    • Communication Log: Enable for debugging
  1. 进入 Administration > Operations > Services 路径
  2. 点击服务配置下的新建按钮
  3. 填写以下信息:
    • Service ID:唯一标识符(例如
      my.api.service
    • Service Type:HTTP、FTP、SOAP等
    • Enabled:勾选以启用服务
    • Profile:选择或创建配置文件
    • Credential:选择或创建凭证
    • Communication Log:调试时可开启

Service Profile Settings

服务配置文件设置

SettingDescription
TimeoutMaximum wait time in milliseconds
Rate LimitMaximum calls per time unit
Circuit Breaker EnabledEnable automatic failure handling
Max Circuit Breaker CallsCalls before circuit opens
Circuit Breaker IntervalTime window for tracking failures
设置项描述
Timeout最大等待时间(毫秒)
Rate Limit单位时间内最大调用次数
Circuit Breaker Enabled开启自动故障处理
Max Circuit Breaker CallsCircuit Breaker打开前的最大失败调用次数
Circuit Breaker Interval故障统计的时间窗口

Service Credential Settings

服务凭证设置

SettingDescription
IDCredential identifier
URLBase URL for the service
UserUsername for authentication
PasswordPassword for authentication
设置项描述
ID凭证标识符
URL服务的基础URL
User身份验证用户名
Password身份验证密码

Detailed References

详细参考

  • HTTP Services - REST API integrations
  • FTP/SFTP Services - File transfer operations
  • SOAP Services - SOAP web service integrations
  • Services XML - Import/export service configurations
  • HTTP Services - REST API集成
  • FTP/SFTP Services - 文件传输操作
  • SOAP Services - SOAP Web服务集成
  • Services XML - 导入/导出服务配置

Script API Classes

脚本API类

ClassDescription
dw.svc.LocalServiceRegistry
Create service instances
dw.svc.Service
Base service class
dw.svc.HTTPService
HTTP service methods
dw.svc.FTPService
FTP/SFTP service methods
dw.svc.SOAPService
SOAP service methods
dw.svc.Result
Service call result
dw.svc.ServiceConfig
Service configuration
dw.svc.ServiceProfile
Rate limit/circuit breaker config
dw.svc.ServiceCredential
Authentication credentials
dw.net.HTTPClient
Underlying HTTP client
dw.net.FTPClient
Underlying FTP client
dw.net.SFTPClient
Underlying SFTP client
描述
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
限流/Circuit Breaker配置
dw.svc.ServiceCredential
身份验证凭证
dw.net.HTTPClient
底层HTTP客户端
dw.net.FTPClient
底层FTP客户端
dw.net.SFTPClient
底层SFTP客户端