3. API设计原则:RESTful风格、资源命名规范、版本控制策略、幂等性设计
风控规则引擎的API是业务系统与决策核心之间的桥梁。设计不良的API会导致集成困难、版本混乱、重复扣分甚至数据不一致。本章围绕四个核心原则展开:RESTful风格、资源命名规范、版本控制策略和幂等性设计,确保API既符合业界标准,又能应对风控场景的高并发与强一致性要求。
3.1 RESTful风格:以资源为中心
REST(Representational State Transfer)是一种基于HTTP协议的架构风格。在风控规则引擎中,我们将决策请求、规则集、策略、名单等视为资源,通过标准HTTP方法对其进行操作。
| HTTP方法 | 操作类型 | 风控场景示例 | 响应状态码 |
|---|---|---|---|
| GET | 查询/读取 | 查询某笔订单的决策结果 | 200 OK |
| POST | 创建/提交 | 提交一笔交易进行实时风控审核 | 201 Created |
| PUT | 全量替换 | 更新整个规则集的配置 | 200 OK |
| PATCH | 部分更新 | 修改某条黑名单的有效期 | 200 OK |
| DELETE | 删除 | 移除一条过期的灰名单记录 | 204 No Content |
设计要点:避免在URL中使用动词(如
/submitDecision),应使用名词表示资源(如 /decisions),并通过HTTP方法表达动作。POST用于创建资源,也常用于提交“决策请求”这种不可重复创建的场景,此时需结合幂等性设计。
3.2 资源命名规范:清晰、一致、可预测
资源命名是API的可读性基石。风控规则引擎涉及多种资源类型,命名应遵循以下规范:
- 使用复数名词:
/rules、/decisions、/blacklists,而非/rule、/getDecision。 - 层级关系用斜杠表示:
/rules/{ruleId}/versions表示某个规则的所有版本。 - 查询参数用于过滤和分页:
/decisions?status=reject&page=1&size=20。 - 使用小写字母和连字符:
/risk-profiles而非/riskProfiles或/risk_profiles。 - 避免过深的嵌套:超过三级嵌套建议使用查询参数或扁平化设计。
推荐命名示例:
GET /v2/rules — 获取规则列表POST /v2/decisions — 提交决策请求GET /v2/decisions/{decisionId} — 查询单笔决策结果PUT /v2/strategies/{strategyId}/rules — 替换策略下的规则集合
3.3 版本控制策略:平滑演进,向后兼容
风控规则引擎需要频繁迭代规则逻辑、新增字段或调整决策流程。版本控制是保障客户端不受破坏性变更影响的关键。
推荐采用URL路径版本控制,将版本号显式放在路径中:
GET /v1/decisions/{decisionId}
GET /v2/decisions/{decisionId}
版本控制的核心原则:
- 主版本号(v1, v2):引入不兼容变更时递增,如删除字段、修改响应结构。
- 向后兼容:同一主版本内,只做新增字段或可选参数变更,不破坏已有客户端。
- 版本生命周期:每个版本至少维护6-12个月,提前通知废弃计划。
- 默认版本:新客户端应始终使用最新稳定版本,旧版本逐步下线。
避坑提示:不要使用
Accept 头或查询参数(如 ?version=1)进行版本控制,这会导致缓存混乱和调试困难。URL路径是最直观、最稳定的方式。
3.4 幂等性设计:防止重复扣分与重复决策
在风控场景中,网络超时、客户端重试、消息队列重复投递都可能导致同一笔交易被多次提交。如果API不具备幂等性,就会产生重复扣分、重复审核、重复发送告警等严重问题。
幂等性指无论调用多少次,结果都与调用一次相同。对于风控规则引擎,以下方法需要重点设计幂等:
- POST /decisions:提交决策请求,必须支持幂等。
- PUT /rules/{ruleId}:全量更新规则,天然幂等。
- DELETE /blacklists/{id}:删除操作,重复调用返回相同结果。
幂等性实现方案:客户端令牌(Idempotency-Key)
客户端在请求头中携带一个全局唯一的 Idempotency-Key(如UUID),服务端缓存该Key及其响应结果。当收到相同Key的请求时,直接返回缓存结果,不再重复执行业务逻辑。
POST /v2/decisions
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
{
"transactionId": "TXN20250321001",
"amount": 1500.00,
"userId": "U12345"
}
幂等性设计要点:
• 服务端缓存Idempotency-Key至少24小时,或直到决策结果被确认消费。
• 缓存中不仅存储“成功”响应,也要存储“失败”响应,避免重复执行导致不同错误。
• 对于同一Key,如果请求体不同,应返回
• 在分布式环境下,使用Redis等集中式缓存存储Key-Result映射,保证多实例一致性。
• 服务端缓存Idempotency-Key至少24小时,或直到决策结果被确认消费。
• 缓存中不仅存储“成功”响应,也要存储“失败”响应,避免重复执行导致不同错误。
• 对于同一Key,如果请求体不同,应返回
422 Unprocessable Entity 或 409 Conflict。• 在分布式环境下,使用Redis等集中式缓存存储Key-Result映射,保证多实例一致性。
3.5 原则总结与设计检查清单
| 原则 | 核心要求 | 常见反例 | 风控场景价值 |
|---|---|---|---|
| RESTful风格 | 资源URL + 标准HTTP方法 | /api/submitDecision |
统一接口语义,降低集成成本 |
| 资源命名规范 | 复数名词、小写连字符、层级清晰 | /getRuleById |
API自文档化,减少沟通歧义 |
| 版本控制策略 | URL路径版本号、向后兼容、生命周期管理 | 无版本号或Header版本 | 支持规则快速迭代,不中断线上业务 |
| 幂等性设计 | Idempotency-Key机制、缓存结果、防重复执行 | 依赖客户端自行去重 | 防止重复扣分、重复决策,保障资金安全 |
设计检查清单:
✅ 所有POST请求是否都支持Idempotency-Key?
✅ 资源URL是否全部使用名词复数形式?
✅ 当前API版本号是否显式标注在URL中?
✅ 是否制定了版本废弃时间表并通知了所有调用方?
✅ 幂等缓存是否使用集中式存储(如Redis)?
✅ 所有POST请求是否都支持Idempotency-Key?
✅ 资源URL是否全部使用名词复数形式?
✅ 当前API版本号是否显式标注在URL中?
✅ 是否制定了版本废弃时间表并通知了所有调用方?
✅ 幂等缓存是否使用集中式存储(如Redis)?