7.6 KiB
7.6 KiB
For AI assistants: Read this entire file before designing or implementing any API. Contract rules here are mandatory. Do not invent per-module variants unless explicitly allowed.
Fonrey API 契约规范(API_CONTRACT)
版本: 1.0
适用范围: 全模块(account / permission / property / client / complex / org / setting)
关联总纲: TECH_STACK/TECH_STACK.md
最后更新: 2026-04-27
1. 文档定位与原则
本文件定义 Fonrey 全局 API 契约标准,解决跨模块接口风格漂移问题。模块技术方案中的 API 章节必须遵循本文件,不得各自定义冲突规则。
1.1 强制级别
- MUST:必须遵守,违反视为缺陷
- SHOULD:建议遵守,若不遵守需在模块文档注明原因
- MAY:可选能力
1.2 适用接口类型
- JSON API(
/api/**) - HTMX 片段端点(HTML response)
- 文件上传/下载端点
2. 请求 / 响应格式规范
2.1 请求体规范(JSON API)
Content-TypeMUST 为application/jsoncharset=utf-8SHOULD 显式声明- 写操作(POST/PUT/PATCH)MUST 传业务 payload;禁止空对象写入
推荐请求结构:
{
"data": {
"...": "业务字段"
},
"meta": {
"request_id": "可选,客户端透传"
}
}
兼容说明:历史端点已存在 filters/sort/pagination 平铺结构时可继续使用,但新接口 SHOULD 迁移到 data 容器。
2.2 成功响应规范(JSON API)
成功响应 MUST 使用统一 envelope:
{
"ok": true,
"data": {},
"meta": {
"request_id": "uuid",
"timestamp": "2026-04-27T16:30:00+08:00"
}
}
说明:
okMUST 为truedataMUST 存在(可为空对象{}或空数组[])metaSHOULD 包含request_id与服务端时间
2.3 失败响应规范(JSON API)
失败响应 MUST 使用统一 envelope:
{
"ok": false,
"error": "权限不足",
"code": "PROPERTY_PERMISSION_DENIED",
"details": {},
"meta": {
"request_id": "uuid",
"timestamp": "2026-04-27T16:30:00+08:00"
}
}
说明:
errorMUST 为面向用户/调用方可读消息codeMUST 为稳定机器可读码(大写下划线)detailsMAY 提供字段级错误(如校验失败)
2.4 HTMX 响应规范
- 成功:返回 HTML 片段;必要时通过
HX-Trigger触发前端事件 - 失败:
- 状态码 MUST 正确(4xx/5xx)
- SHOULD 在响应头返回
HX-Trigger,例如:{"toast:error":"权限不足"}{"toast:error":"请求失败,请重试"}
3. 错误码规范
3.1 命名规则
- 错误码 MUST 为
UPPER_SNAKE_CASE - 推荐前缀:
<MODULE>_(如PROPERTY_/CLIENT_/ORG_)
3.2 HTTP 状态码基线
| HTTP | 使用场景 | 示例 code |
|---|---|---|
| 400 | 参数错误、业务前置条件不满足 | PROPERTY_VALIDATION_ERROR |
| 401 | 仅用于纯 API Token 鉴权失败(当前 Web 会话模式一般不用) | AUTH_UNAUTHORIZED |
| 403 | 已登录但无权限 | *_PERMISSION_DENIED |
| 404 | 资源不存在或不可见 | *_NOT_FOUND |
| 409 | 状态冲突、任务未就绪 | *_STATE_CONFLICT / *_JOB_NOT_READY |
| 422 | 字段级校验错误(可选) | *_VALIDATION_FAILED |
| 429 | 频控触发 | RATE_LIMITED |
| 500 | 未预期异常 | INTERNAL_ERROR |
3.3 稳定性要求
codeMUST 可稳定依赖,不得频繁改名- 错误文案
error可优化,但不应影响调用方流程判断
4. 分页规范
Fonrey 列表查询 MUST 使用 Keyset 分页;禁止 OFFSET 深分页。
4.1 请求格式
{
"filters": {},
"sort": {"field": "updated_at", "order": "desc"},
"pagination": {"mode": "keyset", "cursor": null, "limit": 20}
}
4.2 响应格式
{
"ok": true,
"data": {
"items": [],
"next_cursor": "opaque_cursor_2"
},
"meta": {
"pagination": {"mode": "keyset", "cursor": "opaque_cursor", "limit": 20}
}
}
4.3 约束
limitMUST 有上限(建议 ≤ 100)cursorMUST 为不透明字符串,禁止暴露内部排序字段组合- 排序字段 MUST 来自白名单,防止 SQL 注入与慢查询
5. 搜索 / 筛选规范
5.1 推荐请求结构
{
"filters": {
"keyword": "保利",
"status": ["active", "pending"],
"district_id": "uuid"
},
"sort": {"field": "updated_at", "order": "desc"},
"pagination": {"mode": "keyset", "cursor": null, "limit": 20}
}
5.2 语义规范
keyword:模糊检索词(服务端统一做 trim)- 多选条件 MUST 使用数组(如
status: []) - 空数组
[]语义:不限制该条件 null语义:由模块文档明确(默认建议等同“不传”)
5.3 安全与性能
- 仅允许白名单字段参与筛选和排序
- LIKE/全文检索字段 SHOULD 建立索引或搜索策略
- 查询快照哈希(用于缓存/导出)SHOULD 对 filters+sort+scope 进行规范化后计算
6. 上传规范
Fonrey 优先采用“预签名上传 + 回执提交(commit)”两段式。
6.1 标准流程
- 客户端请求 upload-token(业务 API)
- 客户端直传对象存储(R2)
- 客户端调用 commit API 回写元数据
6.2 合约要求
- upload-token MUST 短时有效(建议 5~15 分钟)
- commit MUST 幂等(建议支持
idempotency_key) - 上传白名单与大小限制 MUST 在模块文档声明并在服务端校验
- SHOULD 校验
content_type与size - MAY 增加
sha256校验确保完整性
6.3 错误码建议
*_UPLOAD_TOKEN_EXPIRED(409/400)*_UPLOAD_FILE_TOO_LARGE(400)*_UPLOAD_FILE_TYPE_NOT_ALLOWED(400)*_UPLOAD_COMMIT_CONFLICT(409)
7. 文件下载规范
下载统一采用“导出任务 + 状态查询 + download endpoint”。
7.1 标准流程
- 创建导出任务
POST /api/**/export/jobs/ - 轮询任务状态
GET /api/**/export/jobs/{job_id}/ - 下载结果
GET /api/**/export/jobs/{job_id}/download/
7.2 合约要求
- 任务未完成下载 MUST 返回
409+*_EXPORT_JOB_NOT_READY - 下载链接 SHOULD 为一次性或短时有效 URL
- 响应 SHOULD 设置
Content-Disposition(附件下载) - 文件名 SHOULD 带模块与日期,便于审计
8. 权限拒绝返回规范
8.1 JSON API
- 未登录:MUST 返回
302(Web Session 场景)或401(纯 API 场景) - 已登录无权限:MUST 返回
403 - 失败体 MUST 使用统一错误 envelope,
code为*_PERMISSION_DENIED
8.2 页面路由(SSR/HTMX)
- 未登录:302 跳转登录页
- 已登录无权限:403 页面(或 HTMX 403 片段)
- HTMX 拒绝 SHOULD 触发
HX-Triggertoast 事件
8.3 测试强约束
每个受保护端点 MUST 覆盖三态:
- 200(有权限)
- 403(已登录无权限)
- 302/401(未登录,视端点类型)
9. 与模块文档的衔接规则
- 各模块技术方案中的“四、API 设计原则”“六、关键 API 规范”“十二、错误码建议”必须引用本文件
- 模块文档可补充模块特有 code 与字段,但不得与本规范冲突
- 冲突时以本文件为准;若需例外,必须在模块文档显式记录 ADR 链接
10. 落地检查清单(Review Checklist)
- 是否使用统一成功/失败 envelope
- 错误码是否为稳定
UPPER_SNAKE_CASE - 列表接口是否全部 Keyset 分页
- filters/sort 字段是否白名单化
- 上传是否采用 token+commit 且具备幂等保障
- 下载是否采用 job 流程并处理未就绪 409
- 权限拒绝是否遵循 200/403/302(401) 三态
- 测试是否覆盖契约关键路径