4. RESTful API 设计原则:评分接口规范、请求/响应数据结构设计、错误码与异常处理

在风控评分通道的 Model Serving 实践中,API 是上游业务系统与模型推理引擎之间的唯一契约。一个设计良好的 RESTful 评分接口,不仅要保证数据交换的准确性与实时性,还必须具备清晰的语义、健壮的异常处理机制以及可扩展的数据结构。本章围绕评分接口的规范、请求/响应结构设计以及错误码体系展开,确保接口在生产环境中具备高可用性与可维护性。

4.1 评分接口规范

评分接口遵循标准的 RESTful 风格,使用 HTTP POST 方法提交特征数据并获取评分结果。接口路径设计应体现资源语义,避免动词化。

规范项 要求 说明
HTTP 方法 POST 评分请求通常包含敏感特征数据,POST 可避免 URL 长度限制与日志泄露
接口路径 /api/v1/score 版本号置于路径中,便于多版本共存与灰度切换
Content-Type application/json 统一使用 JSON 格式,支持嵌套结构与动态字段
幂等性 非幂等 每次评分可能因模型版本、时间窗口特征产生不同结果,不强制幂等
超时设置 500ms ~ 3000ms 根据特征工程复杂度与模型推理耗时动态配置,超时返回 504
实践建议:接口路径中的版本号建议使用整数主版本(v1, v2),避免使用日期或语义化版本号,以降低上游调用方的适配成本。

4.2 请求数据结构设计

评分请求体采用扁平化 JSON 对象,包含三个核心字段:request_id、features、context。其中 features 为必填字段,承载模型推理所需的全部特征变量。

{
  "request_id": "202503211234567890001",
  "features": {
    "age": 35,
    "income": 250000,
    "credit_limit": 50000,
    "loan_amount": 120000,
    "loan_term": 36,
    "overdue_days_30": 0,
    "overdue_days_90": 1,
    "query_count_3m": 5,
    "existing_loans": 2
  },
  "context": {
    "channel": "APP",
    "product_code": "P001",
    "timestamp": "2025-03-21T14:30:00+08:00"
  }
}
字段 类型 必填 说明
request_id string 是 全局唯一请求标识,用于链路追踪与去重
features object 是 特征键值对,键名与模型训练特征一致,值类型支持 number/string/boolean
context object 否 请求上下文,包含渠道、产品码、时间戳等元信息,用于策略分流与日志审计
避坑提示:特征字段名禁止使用特殊字符(如空格、点号、连字符),建议统一使用下划线命名法。模型训练与线上推理的特征字典必须严格对齐,否则会导致推理异常或评分偏差。

4.3 响应数据结构设计

评分响应体同样采用 JSON 格式,包含 code、message、data 三个顶层字段。其中 data 字段封装评分结果与辅助信息,便于上游系统直接消费。

{
  "code": 0,
  "message": "success",
  "data": {
    "score": 725,
    "decision": "approve",
    "reason_code": "R001",
    "model_version": "v2.3.1",
    "score_timestamp": "2025-03-21T14:30:01.123+08:00",
    "extra": {
      "probability": 0.87,
      "bucket": "A"
    }
  }
}
字段 类型 必填 说明
code int 是 业务状态码,0 表示成功,非 0 表示异常
message string 是 状态描述,成功时为 "success",异常时返回具体错误信息
data.score int 是 模型输出的信用评分,范围 0~1000
data.decision string 是 策略决策结果:approve / reject / review
data.reason_code string 否 拒绝或人工审核的原因码,用于下游解释
data.model_version string 是 实际执行推理的模型版本号,用于审计与回滚追溯
data.extra object 否 扩展字段,可携带概率值、分桶、特征贡献度等辅助信息
设计要点:响应体中的 data 对象应保持稳定,新增字段优先放入 extra 子对象,避免破坏已有调用方的解析逻辑。

4.4 错误码与异常处理

错误码体系采用分层设计,分为 HTTP 状态码与业务状态码两层。HTTP 状态码用于表示通信层面的成功或失败,业务状态码用于表示评分业务层面的具体异常类型。

错误码分层处理流程 HTTP 状态码层 业务状态码层 异常处理层 200 OK / 400 Bad Request 401 Unauthorized 429 Too Many Requests 500 Internal Server Error 1001 特征缺失 1002 特征类型错误 2001 模型推理超时 3001 策略引擎异常 重试机制(指数退避) 降级策略(缓存/默认分) 熔断保护(滑动窗口) 告警通知(钉钉/邮件) 说明:HTTP 状态码标识通信结果,业务状态码标识评分异常类型,异常处理层执行恢复策略 三者协同工作,确保接口的健壮性与可观测性

4.4.1 HTTP 状态码定义

HTTP 状态码 含义 典型场景
200 请求成功 评分正常返回,业务状态码为 0
400 请求参数错误 缺少必填字段、特征值格式错误、JSON 解析失败
401 认证失败 API Key 无效或过期
429 请求频率超限 超过 QPS 配额,返回 Retry-After 头部
500 服务端内部错误 模型加载失败、数据库连接异常、未知运行时错误
504 网关超时 模型推理超过配置的超时阈值

4.4.2 业务状态码定义

业务码 分类 说明 处理建议
0 成功 评分正常完成 直接消费 data 字段
1001 参数校验 必填特征缺失 检查请求体 features 字段完整性
1002 参数校验 特征值类型错误 核对特征类型与模型要求一致
1003 参数校验 特征值超出合法范围 检查特征值是否在训练集分布范围内
2001 推理异常 模型推理超时 优化特征工程或升级推理硬件
2002 推理异常 模型版本不存在 检查 model_version 配置或回滚版本
3001 策略异常 策略引擎执行失败 检查策略规则配置与依赖数据源
4001 限流熔断 请求被限流 降低请求频率或申请提升配额
5001 系统异常 未知内部错误 联系运维查看服务端日志

4.4.3 异常处理策略

  • 重试机制:对于 504 网关超时与 2001 模型推理超时,采用指数退避重试策略,初始间隔 200ms,最大重试次数 3 次。
  • 降级策略:当模型服务不可用时,根据 context.product_code 返回预设的默认评分或缓存评分,确保业务连续性。
  • 熔断保护:基于滑动窗口统计错误率,当 30 秒内错误率超过 50% 时触发熔断,熔断时长 60 秒,熔断期间直接返回降级结果。
  • 告警通知:业务码 3001 及以上异常自动触发告警,通过钉钉/企业微信机器人通知值班人员,并记录完整请求日志用于事后分析。
最佳实践:所有异常响应必须包含 request_id 字段,便于上下游系统快速关联日志,定位问题根因。建议在响应头中也透传 X-Request-Id。

4.5 接口安全与版本管理

评分接口涉及用户敏感特征数据,必须实施传输层安全与访问控制。同时,接口版本管理应支持平滑升级与灰度切换。

接口版本管理与灰度切换流程 API 网关 v1 稳定版本 100% 流量 v2 灰度版本 5% 流量 v2 全量版本 100% 流量 说明:API 网关根据请求路径中的版本号(/api/v1/score vs /api/v2/score)路由到不同模型服务 灰度阶段通过网关权重配置逐步放量,监控评分分布与错误率,确认稳定后切换全量
  • 传输安全:强制使用 HTTPS,TLS 版本不低于 1.2,证书由内部 CA 签发或使用云厂商托管证书。
  • 访问控制:请求头携带 X-API-Key 字段,网关层校验有效性,支持按渠道、产品码进行细粒度权限控制。
  • 版本管理:路径版本号(v1, v2)与模型版本解耦,接口版本升级时保留旧版本至少 3 个月,通过网关权重配置实现灰度切换。
  • 审计日志:所有评分请求与响应均记录至审计日志系统,包含 request_id、时间戳、调用方身份、模型版本、评分结果,满足合规要求。
安全提醒:禁止在响应体中返回原始特征数据或模型参数,防止敏感信息泄露。审计日志中的特征数据应进行脱敏处理,如对身份证号、手机号等字段进行掩码。