第5章:返回规范
5.1 统一返回结构
所有 API 返回均采用统一的 JSON 格式,包含以下字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| success | Boolean | 是 | 请求是否成功,true 表示成功,false 表示失败 |
| errorCode | Integer | 否 | 错误码。当 success=true 时,该字段为 null;当 success=false 时,该字段有值(详见错误码说明或错误码索引) |
| errorMsg | String | 否 | 错误信息。当 success=true 时,该字段为 null;当 success=false 时,该字段有值 |
| result | Object/Array | 否 | 实际返回数据内容,不同接口结构不同 |
| pagination | Object | 否 | 分页信息,仅在分页查询接口中返回 |
成功响应示例:
{
"success": true,
"errorCode": null,
"errorMsg": null,
"result": {
"orderNo": "OUT202411010001",
"status": "CREATED"
}
}
失败响应示例:
{
"success": false,
"errorCode": 401,
"errorMsg": "用户认证失败",
"result": null
}
5.2 成功返回示例
5.2.1 无数据返回(操作成功)
{
"success": true,
"errorCode": null,
"errorMsg": null,
"result": null
}
说明:
success = true表示业务处理成功errorCode = null和errorMsg = null表示请求成功,无错误信息result = null表示无返回数据(常见于创建、更新、删除等操作)
5.2.2 单个对象返回
{
"success": true,
"errorCode": null,
"errorMsg": null,
"result": {
"skuCode": "SKU123456",
"skuName": "iPhone 15 Case",
"createdTime": "2025-11-07 10:00:00"
}
}
说明:
success = true表示业务处理成功errorCode = null和errorMsg = null表示请求成功,无错误信息result字段返回接口的实际业务数据对象
5.2.3 数组返回
{
"success": true,
"errorCode": null,
"errorMsg": null,
"result": [
{
"skuCode": "SKU123456",
"skuName": "iPhone 15 Case"
},
{
"skuCode": "SKU123457",
"skuName": "iPhone 15 Pro Case"
}
]
}
说明:
success = true表示业务处理成功errorCode = null和errorMsg = null表示请求成功,无错误信息result字段返回数组类型的数据
5.3 失败返回示例
5.3.1 参数校验失败
{
"success": false,
"errorCode": 1000,
"errorMsg": "无效的参数",
"result": null
}
5.3.2 业务逻辑错误
{
"success": false,
"errorCode": 2003,
"errorMsg": "当前的数据不支持此操作",
"result": null
}
5.3.3 系统错误
{
"success": false,
"errorCode": 500,
"errorMsg": "服务器错误",
"result": null
}
说明:
success = false表示请求处理失败errorCode为错误码,用于区分不同的错误类型errorMsg为错误信息描述result = null表示请求失败,无返回数据
5.4 分页返回结构
当接口支持分页返回时,会在响应中包含 pagination 字段,result 字段为数组类型。
分页字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
| current | Integer | 当前页码,从 1 开始 |
| pageSize | Integer | 每页条数 |
| total | Long | 数据总条数 |
分页返回示例
{
"success": true,
"errorCode": null,
"errorMsg": null,
"result": [
{
"orderNo": "OUT202411010001",
"status": "CREATED"
},
{
"orderNo": "OUT202411010002",
"status": "SHIPPED"
}
],
"pagination": {
"current": 1,
"pageSize": 20,
"total": 125
}
}
说明:
result为当前页的数据列表pagination.current表示当前页码pagination.pageSize表示每页条数pagination.total表示数据总条数
5.5 字段命名规范
1. 统一采用驼峰命名(如:orderNo, createTime)
2. 所有日期时间字段统一使用:
- 格式:MM/dd/yyyy HH:mm:ss
- 时区:America/Los_Angeles(洛杉矶时区)
3. 金额类字段统一以 USD 为单位,保留两位小数
5.6 响应状态判断
客户端应根据 success 字段判断请求是否成功:
- success = true:请求成功,可以读取
result字段获取业务数据 - success = false:请求失败,应读取
errorCode和errorMsg字段获取错误信息
5.7 错误码说明
本章节定义 WMS 对外 API 的系统级错误码,用于标识框架、认证或系统相关问题。
5.7.1 系统级错误码
说明:以下为当前已定义的系统级错误码,错误码列表将持续补充完善。
| 错误码 | HTTP Code | 错误描述 | 可能原因 | 解决建议 |
|---|---|---|---|---|
| 200 | 200 | 请求处理成功 | - | - |
| 401 | 401 | 用户认证失败 | Token 无效或过期 | 重新获取 Token |
| 403 | 403 | 权限不足 | 无访问权限 | 联系管理员确认权限 |
| 405 | 405 | 验证码校验失败 | 验证码错误 | 重新输入验证码 |
| 500 | 200 | 服务器错误 | 后端服务异常 | 稍后重试或联系技术支持 |
| 1000 | 200 | 无效的参数 | 必填参数为空或格式不符 | 检查请求参数是否完整、格式正确 |
| 1006 | 200 | 不支持的请求参数 | 请求参数格式错误 | 检查请求参数格式 |
| 1007 | 200 | 不支持的请求类型 | HTTP 方法错误 | 检查请求方法(GET/POST/PUT/DELETE) |
| 1012 | 200 | 第三方初始化失败 | 第三方服务初始化异常 | 联系技术支持 |
| 2003 | 200 | 当前的数据不支持此操作 | 数据状态不允许当前操作 | 检查数据状态 |
注意:错误码列表将持续更新,如遇到未列出的错误码,请查看
errorMsg字段获取详细错误信息,或联系技术支持。
5.7.2 错误响应示例
示例1:参数校验失败
{
"success": false,
"errorCode": 1000,
"errorMsg": "无效的参数",
"result": null
}
示例2:认证失败
{
"success": false,
"errorCode": 401,
"errorMsg": "用户认证失败",
"result": null
}
示例3:数据状态错误
{
"success": false,
"errorCode": 2003,
"errorMsg": "当前的数据不支持此操作",
"result": null
}
示例4:系统错误
{
"success": false,
"errorCode": 500,
"errorMsg": "服务器错误",
"result": null
}
5.7.3 错误处理最佳实践
5.7.3.1 错误分类处理
重要说明:只有 500 错误码可以重试,其他所有错误码都不可以重试。
500 服务器错误(可以重试)
错误码:500
处理策略:
- ✅ 可以重试:服务器临时错误,可以适当重试
- ✅ 指数退避:实现指数退避重试策略
- ✅ 限制重试次数:最多重试 3 次
- ✅ 记录日志:记录重试日志,便于排查问题
重试策略:
- 第1次重试:等待 1 秒
- 第2次重试:等待 2 秒
- 第3次重试:等待 4 秒
示例处理代码(Java):
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.TimeUnit;
public class ApiClient {
private static final int MAX_RETRIES = 3;
private RestTemplate restTemplate;
/**
* 发送请求,仅对 500 错误进行重试
*/
public Map<String, Object> sendRequestWithRetry(String url, Object request) {
int retryCount = 0;
while (retryCount <= MAX_RETRIES) {
try {
ResponseEntity<Map> response = restTemplate.postForEntity(
url, request, Map.class);
Map<String, Object> body = response.getBody();
// 如果成功,直接返回
if (body != null && Boolean.TRUE.equals(body.get("success"))) {
return body;
}
// 只有 500 错误码可以重试
if (body != null && body.get("errorCode") != null && (Integer) body.get("errorCode") == 500) {
if (retryCount < MAX_RETRIES) {
// 指数退避:1秒、2秒、4秒
long waitTime = (long) Math.pow(2, retryCount);
Thread.sleep(waitTime * 1000);
retryCount++;
continue;
}
}
// 其他错误码或重试次数已用完,直接返回
return body;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("请求被中断", e);
} catch (Exception e) {
// 网络异常等,如果是最后一次重试,抛出异常
if (retryCount >= MAX_RETRIES) {
throw new RuntimeException("请求失败,已重试 " + MAX_RETRIES + " 次", e);
}
// 指数退避后重试
try {
long waitTime = (long) Math.pow(2, retryCount);
Thread.sleep(waitTime * 1000);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("请求被中断", ie);
}
retryCount++;
}
}
throw new RuntimeException("请求失败,已重试 " + MAX_RETRIES + " 次");
}
}
其他错误码(不可重试)
错误码范围:除 500 外的所有错误码(包括 400、401、403、404、429、1000、1006、1007、1012、2003 等)
处理策略:
- ❌ 不可重试:这些错误通常是参数问题、权限问题、业务逻辑问题或限流问题,重试不会解决问题
- ✅ 检查请求参数:仔细检查请求参数是否符合要求
- ✅ 检查认证信息:对于 401 错误,确认 Token 是否有效
- ✅ 检查权限:对于 403 错误,确认账号是否有访问权限
- ✅ 降低请求频率:对于 429 错误,降低请求频率,实现客户端限流
- ✅ 修正后重新请求:修正问题后重新发送请求(不是自动重试)
常见错误码:
400/1000- 无效的参数:检查请求参数是否完整、格式正确401- 用户认证失败:重新获取 Token403- 权限不足:联系管理员确认权限404- 资源不存在:检查请求的资源路径是否正确429- 请求频率过高:降低请求频率,实现客户端限流1006- 不支持的请求参数:检查请求参数格式1007- 不支持的请求类型:检查请求方法(GET/POST/PUT/DELETE)1012- 第三方初始化失败:联系技术支持2003- 当前的数据不支持此操作:检查数据状态
示例处理代码(Java):
public void handleError(Map<String, Object> response) {
if (response == null || Boolean.TRUE.equals(response.get("success"))) {
return;
}
Integer errorCode = (Integer) response.get("errorCode");
String errorMsg = (String) response.get("errorMsg");
// 只有 500 错误可以重试,其他错误都不可以重试
if (errorCode != null && errorCode == 500) {
// 500 错误会在重试逻辑中处理
return;
}
// 其他错误码,根据错误类型进行处理,但不自动重试
switch (errorCode) {
case 401:
// Token 过期,重新获取 Token(不是重试原请求)
refreshToken();
break;
case 403:
// 权限不足,记录日志并通知管理员
log.error("权限不足: {}", errorMsg);
notifyAdmin("权限不足,请联系管理员");
break;
case 429:
// 限流错误,降低请求频率
log.warn("请求频率过高: {}", errorMsg);
reduceRequestRate();
break;
case 1000:
case 1006:
case 1007:
// 参数错误,检查并修正参数(不是重试)
log.error("参数错误 [{}]: {}", errorCode, errorMsg);
validateAndFixParameters();
break;
default:
// 其他错误,记录日志
log.error("请求失败 [{}]: {}", errorCode, errorMsg);
break;
}
// 注意:这里不进行自动重试,需要人工介入或修正问题后重新请求
}
5.7.3.2 业务错误处理
批量操作部分失败
场景:批量创建商品、批量创建出库订单等
处理策略:
1. 检查返回结果,查看每个条目的处理状态
2. 对于失败的条目,根据错误信息修正后重新提交
3. 建议分批提交,每批不超过 100 条
4. 实现重试机制,对失败的条目进行重试
示例响应:
{
"success": true,
"errorCode": null,
"errorMsg": null,
"result": {
"successResultList": [
{
"orderNo": "OUT202411010001",
"referenceNo": "ORDER-001",
"success": true,
"errorCode": null,
"errorMsg": null
}
],
"failedResultList": [
{
"orderNo": null,
"referenceNo": "ORDER-002",
"success": false,
"errorCode": 1000,
"errorMsg": "SKU不存在"
}
]
}
}
处理代码(Java):
import java.util.ArrayList;
import java.util.List;
public class BatchOperationHandler {
/**
* 处理批量操作结果,提取失败的条目
*/
public void handleBatchResult(Map<String, Object> response,
List<Map<String, Object>> originalRequest) {
List<Map<String, Object>> successList = (List<Map<String, Object>>) response.get("successResultList");
List<Map<String, Object>> failedList = (List<Map<String, Object>>) response.get("failedResultList");
// 处理成功的条目
if (successList != null && !successList.isEmpty()) {
for (Map<String, Object> successItem : successList) {
// success 字段为 true,errorCode 和 errorMsg 为 null
if (Boolean.TRUE.equals(successItem.get("success"))) {
// 保存成功的订单信息
saveSuccessOrder((String) successItem.get("orderNo"), (String) successItem.get("referenceNo"));
}
}
}
// 处理失败的条目
if (failedList != null && !failedList.isEmpty()) {
List<FailedItem> failedItems = new ArrayList<>();
for (Map<String, Object> failedItem : failedList) {
// success 字段为 false,errorCode 和 errorMsg 有值
if (Boolean.FALSE.equals(failedItem.get("success"))) {
FailedItem item = new FailedItem();
item.setReferenceNo((String) failedItem.get("referenceNo"));
item.setErrorCode((Integer) failedItem.get("errorCode"));
item.setErrorMsg((String) failedItem.get("errorMsg"));
failedItems.add(item);
}
}
// 记录失败信息,后续人工处理或修正后重新提交
logFailedItems(failedItems);
// 注意:这里不进行自动重试,需要根据错误信息修正后重新提交
// 例如:如果是参数错误,修正参数后重新调用接口
}
}
private void saveSuccessOrder(String orderNo, String referenceNo) {
// 保存成功的订单信息
}
private void logFailedItems(List<FailedItem> failedItems) {
// 记录失败信息,便于后续处理
for (FailedItem item : failedItems) {
log.error("订单创建失败 - referenceNo: {}, errorCode: {}, errorMsg: {}",
item.getReferenceNo(), item.getErrorCode(), item.getErrorMsg());
}
}
// 内部类:失败的条目信息
private static class FailedItem {
private String referenceNo;
private Integer errorCode;
private String errorMsg;
// Getters and Setters
public String getReferenceNo() { return referenceNo; }
public void setReferenceNo(String referenceNo) { this.referenceNo = referenceNo; }
public Integer getErrorCode() { return errorCode; }
public void setErrorCode(Integer errorCode) { this.errorCode = errorCode; }
public String getErrorMsg() { return errorMsg; }
public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; }
}
}
5.7.3.3 错误日志记录
建议记录的信息:
1. 请求信息:
- 请求 URL
- 请求方法
- 请求参数(脱敏处理)
- 请求时间
2. 响应信息:
- 响应状态码
- 错误码(errorCode)
- 错误信息(errorMsg)
- 响应时间
3. 环境信息:
- 使用的环境(测试/生产)
- API Key(脱敏处理)
示例日志格式:
[2025-11-13 10:00:00] ERROR
Request: POST /onixport/api/wms/product/create
Status: 400
ErrorCode: 1000
ErrorMsg: 无效的参数
RequestId: abc123
Environment: Production
5.7.3.4 错误监控与告警
建议实现:
1. 错误率监控:监控接口错误率,超过阈值时告警
2. 错误分类统计:统计不同错误码的出现频率
3. 响应时间监控:监控接口响应时间,异常时告警
4. 限流监控:监控 429 错误,及时调整请求频率
5.7.4 调试建议
1. 检查请求参数:确保必填参数完整、格式正确
2. 查看错误码:根据 errorCode 定位错误类型
3. 查看错误信息:errorMsg 字段提供详细的错误描述
4. 检查认证信息:对于 401 错误,检查 Token 是否有效
5. 检查权限:对于 403 错误,确认账号是否有访问权限
6. 重试机制:对于 5xx 错误,建议加入指数退避重试策略
7. 联系支持:如问题持续存在,可联系技术支持并提供请求详情