2. API 基础概念:什么是 API、RESTful API 设计原则、API 的请求与响应结构、HTTP 状态码详解
2.1 什么是 API
API(Application Programming Interface,应用程序编程接口) 是一组定义好的协议、工具和规则,用于不同软件组件之间的通信与数据交换。在精算模型发布场景中,API 充当了“精算引擎”与“前端应用/外部系统”之间的桥梁,允许调用方以标准化方式提交参数、触发计算并获取结果,而无需了解模型内部的实现细节。
精算模型 API 的核心价值:
- 解耦: 模型升级或替换不影响调用方。
- 复用: 同一模型可被多个业务系统(核保、定价、准备金)调用。
- 安全: 通过 API 网关控制访问权限与调用频率。
- 可审计: 每次调用均可记录请求与响应,满足监管合规要求。
2.2 RESTful API 设计原则
REST(Representational State Transfer) 是一种基于 HTTP 协议的架构风格,强调资源导向、无状态和统一接口。精算模型 API 遵循 RESTful 原则可显著提升可维护性与调用方体验。
| 原则 | 说明 | 精算场景示例 |
|---|---|---|
| 资源导向 | 每个 URL 代表一种资源,而非操作 | /api/v1/models/glm-premium |
| 使用标准 HTTP 方法 | GET / POST / PUT / DELETE 对应查、增、改、删 | POST 提交计算请求,GET 获取结果 |
| 无状态 | 每次请求包含所有必要信息,服务端不保存会话 | 请求中携带模型版本、参数、认证令牌 |
| 统一接口 | 资源通过 URI 标识,通过表述(JSON/XML)操作 | 请求体与响应体均为 JSON 格式 |
| 可缓存 | 响应可被缓存以提高性能 | 模型元数据 GET 请求可缓存 5 分钟 |
精算 API 命名规范建议:
例如:
/api/v{version}/{domain}/{model-name}/{action?}例如:
/api/v1/pricing/term-life/calculate、/api/v1/reserving/loss-triangle
2.3 API 的请求与响应结构
一个标准的 RESTful API 调用包含 请求(Request) 和 响应(Response) 两部分。下面以精算模型“计算定期寿险保费”为例,展示完整的请求与响应结构。
2.3.1 请求结构
POST /api/v1/pricing/term-life/calculate HTTP/1.1
Host: actuarial-api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
Accept: application/json
X-Request-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
{
"model_version": "2.1.0",
"input": {
"age": 35,
"gender": "M",
"smoking_status": "non-smoker",
"coverage_amount": 1000000,
"policy_term_years": 20,
"payment_mode": "annual"
},
"options": {
"include_riders": ["accidental_death", "waiver_of_premium"],
"output_currency": "USD"
}
}
| 请求组成部分 | 说明 | 精算关注点 |
|---|---|---|
| HTTP 方法 + URL | 指定操作类型与资源路径 | POST 用于计算,GET 用于查询模型元数据 |
| Headers | 认证、内容类型、请求追踪 | Authorization 用于身份验证;X-Request-Id 用于审计 |
| Body (JSON) | 输入参数与配置选项 | 模型版本、被保人信息、产品选项 |
2.3.2 响应结构
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
X-Execution-Time: 0.342s
{
"status": "success",
"data": {
"annual_premium": 1250.75,
"monthly_premium": 107.35,
"breakdown": {
"base_premium": 980.00,
"accidental_death_rider": 180.50,
"waiver_of_premium_rider": 90.25
},
"assumptions": {
"mortality_table": "CSO_2017",
"interest_rate": 0.035,
"expense_loading": 0.12
}
},
"meta": {
"model_version": "2.1.0",
"execution_time_ms": 342,
"timestamp": "2025-06-15T10:30:00Z"
}
}
| 响应组成部分 | 说明 | 精算关注点 |
|---|---|---|
| HTTP 状态码 | 请求处理结果 | 200 成功,400 参数错误,500 模型异常 |
| Headers | 响应元数据 | X-Execution-Time 用于性能监控 |
| Body (JSON) | 计算结果与元数据 | 保费、假设、模型版本、执行时间 |
2.4 HTTP 状态码详解
HTTP 状态码由三位数字组成,表示服务器对请求的处理结果。在精算模型 API 中,正确使用状态码有助于调用方快速定位问题。
| 分类 | 状态码 | 含义 | 精算 API 典型场景 |
|---|---|---|---|
| 2xx 成功 | 200 OK | 请求成功,响应体包含结果 | 保费计算成功返回 |
| 201 Created | 资源创建成功 | 提交新的模型版本注册 | |
| 202 Accepted | 请求已接受,异步处理中 | 大规模随机模拟任务提交 | |
| 4xx 客户端错误 | 400 Bad Request | 请求参数格式错误或缺失 | 年龄字段为负数、缺少必填参数 |
| 401 Unauthorized | 未提供有效认证凭证 | 缺少或过期 Bearer Token | |
| 404 Not Found | 请求的资源不存在 | 模型版本号错误 | |
| 5xx 服务端错误 | 500 Internal Server Error | 服务器内部异常 | 精算模型运行时异常 |
| 503 Service Unavailable | 服务暂时不可用 | 模型正在热更新或负载过高 |
精算 API 状态码使用避坑:
- 不要将业务逻辑错误(如“死亡率超出预期范围”)映射为 500,应使用 400 并在响应体中提供详细错误码。
- 对于异步计算任务,使用 202 配合
Location头返回结果查询 URL。 - 所有 5xx 错误必须记录完整堆栈,并返回
X-Request-Id以便追踪。
2.5 精算 API 错误响应规范
当请求失败时,响应体应包含结构化的错误信息,方便调用方程序化处理。
HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Request-Id: f9e8d7c6-b5a4-3210-fedc-ba9876543210
{
"status": "error",
"error": {
"code": "INVALID_INPUT",
"message": "年龄字段 'age' 的值 -5 无效,必须介于 18 到 100 之间。",
"details": [
{
"field": "age",
"value": -5,
"constraint": "range [18, 100]"
}
]
},
"meta": {
"model_version": "2.1.0",
"timestamp": "2025-06-15T10:35:00Z"
}
}
| 错误字段 | 说明 | 示例 |
|---|---|---|
| code | 机器可读的错误码 | INVALID_INPUT、MODEL_NOT_FOUND |
| message | 人类可读的错误描述 | “年龄字段 'age' 的值 -5 无效” |
| details | 错误详情列表,支持多字段校验 | 字段名、错误值、约束条件 |
精算模型 API 错误码设计建议:
使用三级错误码体系:
例如:
使用三级错误码体系:
{DOMAIN}_{CATEGORY}_{SPECIFIC}例如:
PRICING_INVALID_AGE、MODEL_VERSION_NOT_FOUND、SIMULATION_TIMEOUT