分页与错误
成功响应
所有成功响应都使用相同外层结构:
json
{
"data": {},
"meta": {
"api_version": "v1"
}
}列表接口的 meta 改为分页信息:
json
{
"page": 1,
"limit": 20,
"total": 125,
"total_pages": 7
}page 默认 1;limit 默认 20、最大 50。非法或小于 1 的值会回退到默认值,超过 50 会截断为 50。
错误响应
json
{
"error": {
"code": "invalid_token",
"message": "访问令牌无效或已撤销。",
"details": []
}
}details 只在存在额外校验信息时出现。客户端应以 HTTP 状态和稳定的 error.code 分支,不要依赖中文 message 文案。
常见状态
| HTTP | 常见 code | 处理建议 |
|---|---|---|
| 400 | invalid_json、invalid_field、invalid_id、empty_update | 修正请求格式或字段 |
| 401 | missing_token、invalid_token、expired_token | 检查 Bearer 头,必要时创建新 Key |
| 403 | insufficient_scope、user_mismatch、account_restricted | 检查 Scope、账号 UUID 或账号状态 |
| 404 | card_not_found、deck_not_found | 检查 ID、分享标识和可见性 |
| 405 | method_not_allowed | 使用端点允许的方法 |
| 413 | payload_too_large | 把 JSON 正文缩小到 64 KB 以内 |
| 422 | invalid_deck、unknown_card_id、invalid_card_back | 显示 details 并修正业务数据 |
| 500 | internal_error | 稍后重试;不要无限快速重试 |
建议的错误处理
js
async function apiRequest(url, options) {
const response = await fetch(url, options)
const payload = await response.json()
if (!response.ok) {
const error = new Error(payload.error?.message || `HTTP ${response.status}`)
error.code = payload.error?.code || 'unknown_error'
error.details = payload.error?.details
throw error
}
return payload
}对 429 或 5xx 可使用带上限的指数退避;对 400、401、403 和 422 不应原样自动重试。