3. API 设计原则:RESTful 设计规范、资源命名、HTTP 方法选择、状态码定义

在支付风控评分通道的 API 设计中,遵循统一的 RESTful 设计规范是保障接口可维护性、可扩展性与团队协作效率的基石。本节将围绕资源命名、HTTP 方法选择与状态码定义三个核心维度展开,确保 API 设计既符合行业标准,又能精准表达风控业务语义。

3.1 RESTful 设计核心规范

REST(Representational State Transfer)是一种基于资源的架构风格。在风控评分通道中,我们将每一次评分请求、规则配置、模型版本、策略集均视为“资源”,通过统一的接口对资源进行增删改查操作。核心规范包括:

  • 无状态性:每次请求包含所有必要信息(如商户 ID、签名、时间戳),服务端不保存客户端会话状态。
  • 统一接口:使用标准 HTTP 方法操作资源,通过 URI 定位资源,通过请求体/查询参数传递业务数据。
  • 资源导向:URI 只表示资源,不表示动作。例如 /v1/score/orders 表示订单评分资源,而非 /v1/score/doScoring。
  • 版本管理:在 URI 中显式携带版本号(如 /v1/、/v2/),避免向后兼容问题。
设计原则速查: 资源 URI 使用名词复数形式,禁止动词;层级关系用斜杠表示;查询参数用于过滤与排序,不用于资源标识。

3.2 资源命名规范

资源命名直接影响 API 的可读性与一致性。支付风控评分通道的资源命名遵循以下规则:

资源类别 命名示例 说明
评分订单 /v1/score/orders 表示所有评分订单的集合
单笔评分订单 /v1/score/orders/{order_id} 通过唯一标识定位单个订单
规则配置 /v1/rules 风控规则集合资源
单条规则 /v1/rules/{rule_id} 通过规则 ID 定位
模型版本 /v1/models 评分模型版本集合
策略集 /v1/strategies 评分策略组合集合
评分结果明细 /v1/score/orders/{order_id}/details 子资源,表示某订单的评分明细
命名避坑: 避免使用下划线(_)或驼峰命名,推荐全小写加连字符(-)。例如使用 risk-level 而非 riskLevel 或 risk_level。

3.3 HTTP 方法选择

每个 HTTP 方法对应一种标准操作。在风控评分通道中,方法选择必须严格遵循语义,避免滥用 POST 或 GET 执行非预期操作。

HTTP 方法 操作语义 风控评分通道典型场景 请求体 响应体
GET 查询资源 查询评分订单列表、查询单笔评分结果、查询规则详情 无 资源表示
POST 创建资源 提交评分请求、创建新规则、注册新模型版本 创建所需数据 新资源表示 + 201
PUT 全量更新资源 更新规则全部字段、替换策略集配置 完整资源数据 更新后资源表示
PATCH 部分更新资源 修改规则状态(启用/禁用)、更新模型版本描述 部分字段数据 更新后资源表示
DELETE 删除资源 删除废弃规则、移除测试模型版本 无 204 无内容
重要约束: 评分请求(POST /v1/score/orders)是幂等性敏感操作。若业务要求幂等,应在请求头中携带 Idempotency-Key,服务端根据该键去重,避免重复扣分或重复风控判定。

3.4 状态码定义

状态码是 API 响应语义的第一道关口。风控评分通道必须覆盖成功、客户端错误、服务端错误三大类,并针对风控业务扩展特定状态码。

3.4.1 成功状态码

状态码 含义 使用场景
200 OK 请求成功 GET 查询成功、PUT/PATCH 更新成功
201 Created 资源创建成功 POST 创建评分订单、创建规则成功
204 No Content 操作成功,无返回体 DELETE 删除成功、部分异步操作确认

3.4.2 客户端错误状态码

状态码 含义 风控业务典型场景
400 Bad Request 请求参数错误 缺少必填字段、字段格式错误、JSON 解析失败
401 Unauthorized 身份认证失败 签名无效、API Key 过期、时间戳偏差过大
403 Forbidden 无权限访问 商户未开通该评分通道、IP 白名单校验失败
404 Not Found 资源不存在 查询不存在的订单 ID、规则 ID 无效
409 Conflict 资源冲突 重复的幂等键、规则名称已存在、版本号冲突
422 Unprocessable Entity 业务校验失败 评分金额超出限额、风控规则条件逻辑矛盾
429 Too Many Requests 请求频率超限 商户 QPS 超过阈值、触发限流策略

3.4.3 服务端错误状态码

状态码 含义 处理建议
500 Internal Server Error 服务端内部错误 记录错误日志,返回通用错误码,不暴露内部细节
502 Bad Gateway 上游服务不可用 模型推理服务超时、数据库连接异常
503 Service Unavailable 服务暂时过载或维护 返回 Retry-After 头,客户端应等待后重试
状态码最佳实践: 所有错误响应体必须包含 error_code(业务错误码)和 error_message(可读描述),便于客户端快速定位问题。例如:{"error_code": "RATE_LIMIT_EXCEEDED", "error_message": "请求频率超过每秒 100 次限制"}。

3.5 API 设计流程总览

下图展示了从资源识别到状态码定义的完整设计流程,帮助团队在 API 设计阶段建立统一规范。

API 设计流程总览 1. 识别业务资源 2. 资源命名(名词复数) 3. 选择 HTTP 方法(GET/POST/PUT/PATCH/DELETE) 4. 定义请求/响应结构 5. 分配状态码 6. 文档与版本管理

3.6 错误响应体规范

统一的错误响应结构有助于客户端实现通用错误处理逻辑。推荐使用以下 JSON 格式:

{
  "error_code": "INVALID_PARAMETER",
  "error_message": "字段 'amount' 必须为正整数",
  "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "timestamp": "2025-03-21T10:30:00Z",
  "details": [
    {
      "field": "amount",
      "reason": "金额不能为负数",
      "value": -100
    }
  ]
}
提示: request_id 字段必须由服务端生成并返回,便于后续日志追踪与问题排查。客户端在报错时应主动提供该 ID 给技术支持。

3.7 幂等性设计

支付风控场景对幂等性要求极高,避免因网络重试导致重复评分或重复扣减。设计要点如下:

  • 幂等键机制:客户端在 POST 请求头中携带 Idempotency-Key,服务端缓存该键与响应结果,相同键的重复请求直接返回缓存结果。
  • 键有效期:建议幂等键有效期为 24 小时,过期后允许重新提交。
  • 键生成规则:推荐使用 UUID v4,确保全局唯一。
  • 冲突处理:若幂等键已存在但请求体不一致,返回 409 Conflict。
// 幂等评分请求示例
POST /v1/score/orders
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{
  "merchant_id": "M10086",
  "order_id": "ORD20250321001",
  "amount": 29900,
  "currency": "CNY",
  "payee_account": "2088****1234"
}
注意: GET、PUT、DELETE 方法本身具有幂等性,无需额外实现幂等键。PATCH 方法视具体实现而定,若为增量更新则建议也支持幂等键。

3.8 分页与过滤设计

对于列表查询接口(如查询评分订单列表),必须支持分页与过滤,避免一次性返回大量数据导致性能问题。

参数 类型 说明 示例
page integer 页码,从 1 开始 ?page=1
page_size integer 每页条数,默认 20,最大 100 ?page_size=50
status string 按状态过滤 ?status=approved
created_at_gt string (ISO 8601) 创建时间大于 ?created_at_gt=2025-03-01T00:00:00Z
sort_by string 排序字段,支持 created_at、amount ?sort_by=-created_at(降序)
// 分页响应示例
{
  "data": [
    {
      "order_id": "ORD20250321001",
      "status": "approved",
      "score": 85,
      "created_at": "2025-03-21T10:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 20,
    "total_count": 156,
    "total_pages": 8
  }
}
设计要点: 分页响应必须包含 total_count 和 total_pages,方便客户端渲染分页控件。排序字段使用前缀 - 表示降序,无前缀表示升序。

3.9 版本管理策略

API 版本管理是长期维护的必备手段。推荐在 URI 中嵌入版本号,并遵循以下策略:

  • 主版本号:不兼容变更时递增(如 /v1/ → /v2/)。
  • 向后兼容:新增字段、新增可选参数、扩展枚举值均属于兼容变更,无需升级版本。
  • 废弃周期:旧版本至少维护 6 个月,废弃前通过响应头 Deprecation: true 和 Sunset: Sat, 20 Sep 2025 23:59:59 GMT 通知客户端。
  • 版本映射:服务端内部可维护版本路由表,将不同版本的请求映射到对应的处理逻辑。
// 废弃版本响应头示例
HTTP/1.1 200 OK
Deprecation: true
Sunset: Sat, 20 Sep 2025 23:59:59 GMT
Content-Type: application/json

{
  "message": "此 API 版本将于 2025 年 9 月 20 日废弃,请迁移至 /v2/score/orders"
}
最佳实践: 在 API 文档首页明确列出每个版本的当前状态(稳定/废弃/已下线),并附上迁移指南。建议使用 OpenAPI 3.0 规范自动生成文档,确保版本信息与代码同步。