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;同时在网关层对非幂等请求禁止自动重试。上线后同类事故归零。

该案例说明:幂等性不是单个接口的补丁,而是调用方、网关、服务端、存储层共同遵守的契约。接口设计原则只有落到契约、测试与监控上,才能真正保护授信资金安全。