4. API接口设计原则
授信决策引擎的API不是普通业务接口,它直接承载额度审批、利率定价、放款拦截等高风险动作。一次重复调用可能造成重复授信,一次参数篡改可能绕过风控规则,一次版本错配可能让资金方与决策方对同一笔申请得出不同结论。因此,接口设计必须把可预测、可重试、可审计、可演进作为第一目标。本节围绕RESTful风格、幂等性、安全性、版本管理与错误码规范五个维度,给出可落地的设计原则与工程实践。
一、RESTful风格:资源化表达与语义一致性
RESTful的核心不是“用GET和POST”,而是用资源与统一语义描述决策过程。授信决策引擎中,申请、决策任务、额度、规则集都是资源。推荐将决策请求设计为“创建一次决策任务”,而不是“执行一个动作”:
POST /v1/credit-decisions
Content-Type: application/json
X-Request-Id: 7f3c2a91-4b8e-4d2a-9c11-8e5f0a2b6d77
X-Idempotency-Key: IDEM-20240618-000923
{
"applicantId": "CUST-88213",
"productCode": "CASH_LOAN_A",
"amount": 50000,
"term": 12,
"channel": "APP",
"riskData": { "deviceId": "D-9912", "ip": "10.20.31.7" }
}
返回体应包含决策任务ID、状态与决策结果,便于后续查询与对账:
HTTP/1.1 201 Created
Location: /v1/credit-decisions/DEC-20240618-77120
{
"decisionId": "DEC-20240618-77120",
"status": "APPROVED",
"approvedAmount": 50000,
"interestRate": 0.108,
"expireAt": "2024-06-18T12:00:00Z"
}
设计要点:用名词复数表示资源集合;用HTTP方法表达操作语义(GET查询、POST创建、PUT全量更新、PATCH局部更新);用状态码表达结果类别(200成功、201创建、400参数错误、409冲突、422业务拒绝、429限流、500系统异常)。避免在URL中出现/doDecision、/execute这类动词,否则接口会退化为RPC风格,失去缓存、幂等与网关治理的语义基础。
二、幂等性:让重试安全,让资金不重复
授信决策链路长,网络超时、网关重试、上游补偿都会导致同一申请被多次提交。幂等性要求:同一业务请求重复执行,结果与执行一次一致。实现上推荐“幂等键+唯一索引+状态机”三件套:客户端生成X-Idempotency-Key,服务端以该键建立唯一约束;首次请求落库并返回结果,重复请求直接返回首次结果或返回409冲突。
CREATE TABLE idempotent_record (
idem_key VARCHAR(64) PRIMARY KEY,
request_hash VARCHAR(64) NOT NULL,
decision_id VARCHAR(64),
status VARCHAR(16) NOT NULL,
created_at DATETIME NOT NULL,
expire_at DATETIME NOT NULL
);
request_hash,防止同一幂等键被用于不同请求体,否则应返回409并记录告警。对于“查询决策结果”这类天然幂等的GET接口,无需幂等键;对于“创建决策任务”“冻结额度”“放款确认”等写操作,必须强制幂等。若决策引擎内部调用规则集或模型服务,也应传递同一幂等键,形成全链路幂等传递。
三、安全性:身份、传输、权限与审计
授信接口的安全设计至少覆盖四层:
- 身份认证:采用OAuth2 Client Credentials或双向TLS,禁止仅用固定;令牌需短时效并支持吊销。
- 传输安全:全站HTTPS,敏感字段如身份证号、手机号在传输与日志中脱敏或加密。
- 权限控制:按产品、渠道、额度区间做细粒度授权,防止渠道A调用产品B的决策接口。
- 审计与防重放:记录请求ID、调用方、时间戳、决策版本;对写接口校验时间戳与随机数,拒绝过期请求。
四、版本管理与错误码规范:可演进、可定位
版本管理推荐“URL主版本+请求头次版本”的混合策略:URL中保留/v1/表示不兼容变更,兼容性字段扩展通过Accept-Version或请求体中的schemaVersion控制。禁止在同一个URL下静默改变字段含义,否则资金方与决策方会出现“同请求不同结果”的严重问题。
错误码应遵循“HTTP状态码+业务错误码+可读消息+追踪ID”的结构。业务错误码建议分段:1000x参数类、2000x风控拒绝类、3000x额度类、4000x系统与依赖类。示例:
HTTP/1.1 422 Unprocessable Entity
X-Trace-Id: trace-9a8b7c6d
{
"code": "20001",
"message": "风险规则命中:多头借贷超限",
"decisionId": "DEC-20240618-77120",
"retryable": false,
"details": [
{ "rule": "MULTI_LOAN_COUNT", "threshold": 3, "actual": 5 }
]
}
| 维度 | 设计原则 | 反例 | 验证方式 |
|---|---|---|---|
| RESTful | 资源化URL、HTTP语义、状态码一致 | POST /doDecision | 接口评审+契约测试 |
| 幂等性 | 写操作强制幂等键,重复返回首次结果 | 无幂等键直接重试 | 并发重复提交测试 |
| 安全性 | OAuth2/mTLS、脱敏、细粒度授权、防重放 | 固定+明文身份证 | 渗透测试+日志审计 |
| 版本管理 | URL主版本+兼容扩展,禁止静默变更 | 同URL改字段含义 | 多版本回归测试 |
| 错误码 | HTTP+业务码+消息+TraceId,区分可重试 | 全部返回500或“系统错误” | 错误码清单+告警映射 |
五、案例复盘:一次重复授信事故的根因
某现金贷渠道在高峰期出现同一客户两笔授信,金额各5万元。复盘发现:渠道侧网关超时后自动重试,但决策接口未要求幂等键;服务端每次请求都新建决策任务,且额度冻结与决策结果写入不在同一事务。修复方案:写接口强制X-Idempotency-Key,建立唯一索引;决策任务与额度冻结在同一数据库事务内完成;对重复请求返回首次决策结果并记录duplicate=true;同时在网关层对非幂等请求禁止自动重试。上线后同类事故归零。
该案例说明:幂等性不是单个接口的补丁,而是调用方、网关、服务端、存储层共同遵守的契约。接口设计原则只有落到契约、测试与监控上,才能真正保护授信资金安全。