3. API 基础概念回顾:RESTful API 设计原则、HTTP 方法、状态码与请求响应结构

在构建反洗钱(AML)推理服务时,API 是模型与业务系统之间的桥梁。RESTful 风格因其无状态、可缓存、统一接口等特性,成为 AML 在线推理服务的主流架构选择。本节将系统回顾 RESTful API 的核心设计原则、HTTP 方法语义、状态码含义以及请求/响应结构,为后续的 API 发布与推理实践奠定基础。

3.1 RESTful API 六大设计原则

REST(Representational State Transfer)由 Roy Fielding 于 2000 年提出,其核心是围绕资源进行表述状态转移。以下六项原则是判断 API 是否“RESTful”的关键标准:

原则 说明 AML 场景示例
1. 客户端-服务器分离 前端与后端独立演进,仅通过 API 契约交互 AML 规则引擎与模型推理服务分离部署
2. 无状态 每个请求包含所有必要信息,服务端不保存客户端上下文 每次推理请求携带完整的交易特征向量
3. 可缓存 响应隐式或显式标记为可缓存/不可缓存 静态黑名单查询结果可缓存 5 分钟
4. 统一接口 资源通过 URI 标识,使用标准 HTTP 方法操作 POST /api/v1/aml/predict 统一推理入口
5. 分层系统 客户端无法直接感知中间层(负载均衡、网关、代理) API 网关前置认证、限流、日志
6. 按需代码(可选) 服务器可向客户端传输可执行脚本(如 JavaScript) AML 规则热更新脚本下发(较少使用)
实践要点:在 AML 推理 API 设计中,无状态和统一接口是最关键的两条原则。无状态保证了推理节点的水平扩展能力;统一接口降低了业务系统对接的复杂度。
RESTful API 六大设计原则 ① 客户端-服务器分离 独立演进,契约驱动 ② 无状态 请求自包含,不存会话 ③ 可缓存 显式标记缓存策略 ④ 统一接口 URI + HTTP 方法操作资源 ⑤ 分层系统 中间层对客户端透明 ⑥ 按需代码(可选) 服务器下发可执行脚本 核心:以资源为中心,通过标准 HTTP 方法操作资源状态 AML 推理 API 应优先保证无状态与统一接口

3.2 HTTP 方法语义与 AML 场景映射

RESTful API 通过 HTTP 方法表达对资源的操作意图。在 AML 推理服务中,最常用的方法是 POST(创建推理任务)和 GET(查询结果或状态)。以下是标准 HTTP 方法及其在 AML 场景中的典型用法:

HTTP 方法 CRUD 语义 幂等性 AML 推理 API 典型用途
GET 读取资源 是 查询模型版本、获取推理结果、健康检查
POST 创建资源 / 提交处理 否 提交交易进行 AML 推理、批量评分
PUT 全量替换资源 是 更新模型配置、替换规则集
PATCH 部分更新资源 否(通常) 更新推理阈值、调整特征权重
DELETE 删除资源 是 删除过期模型、清理缓存特征
幂等性说明:幂等方法(GET、PUT、DELETE)的多次调用与单次调用效果相同。在 AML 推理中,POST /predict 通常不幂等——每次提交都会生成新的推理记录和唯一 ID。如果业务需要幂等提交,建议在请求头中加入 Idempotency-Key。

3.3 HTTP 状态码:AML 推理 API 的语义信号

状态码是服务器对请求处理结果的标准化反馈。在 AML 推理场景中,合理使用状态码可以帮助客户端快速判断请求状态并采取相应措施。以下是 AML API 最常用的状态码分类:

分类 状态码 含义 AML 场景示例
2xx 成功 200 OK 请求成功,响应体包含结果 同步推理完成,返回风险评分
201 Created 资源创建成功 异步推理任务提交成功,返回任务 ID
4xx 客户端错误 400 Bad Request 请求格式错误或参数无效 特征向量维度不匹配、缺失必填字段
422 Unprocessable Entity 请求语义正确但内容无法处理 交易金额为负数、客户 ID 格式非法
5xx 服务器错误 500 Internal Server Error 服务器内部异常 模型加载失败、推理引擎崩溃
503 Service Unavailable 服务暂时不可用(通常为过载或维护) 模型正在热更新、推理队列满
避坑提示:不要将所有错误都返回 400 或 500。区分 400(格式错误)、422(业务校验失败)、429(限流)和 503(服务不可用)能让客户端做出更精准的容错处理。例如,503 应触发重试,而 400 应触发请求修正。

3.4 请求与响应结构设计

统一的请求/响应结构是 API 可维护性的基石。AML 推理 API 通常采用 JSON 格式,并遵循以下设计规范:

3.4.1 请求结构

一个标准的 AML 推理请求应包含以下层级:

  • 请求头(Headers):认证信息(Authorization: Bearer <token>)、内容类型(Content-Type: application/json)、幂等键(可选)
  • 请求体(Body):包含交易特征、客户信息、上下文元数据
POST /api/v1/aml/predict HTTP/1.1
Host: aml-api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
Idempotency-Key: 7a3b8c9d-1e2f-4a5b-8c7d-9e0f1a2b3c4d

{
  "request_id": "req-20250321-001",
  "timestamp": "2025-03-21T10:30:00Z",
  "transaction": {
    "tx_id": "TX20250321001",
    "amount": 150000.00,
    "currency": "CNY",
    "sender_account": "622202****1234",
    "receiver_account": "621700****5678",
    "channel": "online_banking"
  },
  "customer": {
    "customer_id": "CUST2023001",
    "risk_level": "medium",
    "kyc_status": "verified"
  },
  "features": {
    "amount_zscore": 3.45,
    "tx_frequency_24h": 12,
    "avg_amount_30d": 8500.00,
    "is_high_risk_country": false
  }
}

3.4.2 响应结构

响应应包含状态、数据、元数据三个部分,便于客户端统一解析:

HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req-20250321-001
X-Model-Version: 2.1.0

{
  "status": "success",
  "data": {
    "risk_score": 0.87,
    "risk_level": "high",
    "decision": "block",
    "confidence": 0.94,
    "rule_hits": [
      {"rule_id": "R001", "rule_name": "大额交易", "weight": 0.4},
      {"rule_id": "R007", "rule_name": "高频交易", "weight": 0.3}
    ]
  },
  "meta": {
    "request_id": "req-20250321-001",
    "processing_time_ms": 45,
    "model_version": "2.1.0",
    "timestamp": "2025-03-21T10:30:00.123Z"
  }
}
AML 推理 API 请求与响应结构 请求结构(Request) 请求头(Headers) Authorization: Bearer <token> Content-Type: application/json Idempotency-Key(可选) 请求体(Body) request_id: 全局唯一请求标识 timestamp: ISO 8601 时间戳 transaction: 交易详情 customer: 客户信息 features: 特征向量 响应结构(Response) 响应头(Headers) Content-Type: application/json X-Request-Id: 关联原始请求 X-Model-Version: 模型版本 响应体(Body) status: "success" / "error" data: 推理结果(风险评分、决策) meta: 元数据(处理耗时、版本) error(失败时):错误码 + 描述

3.5 最佳实践与常见反模式

AML API 设计检查清单:
  • ✅ 使用名词复数表示资源集合:/api/v1/aml/transactions 而非 /api/v1/aml/getTransaction
  • ✅ 在 URI 中嵌入版本号:/api/v1/ 或通过 Accept: application/vnd.aml.v1+json
  • ✅ 为异步推理提供 202 Accepted + Location 头 + 轮询端点
  • ✅ 所有响应包含 X-Request-Id 用于链路追踪
  • ❌ 避免在 GET 请求中使用请求体传递参数
  • ❌ 避免返回 200 OK 但体内包含错误信息(应使用 4xx/5xx)
  • ❌ 避免在 URI 中使用动词(如 /predictTransaction),应使用 POST /transactions/predict