重试 API 请求时避免重复创建数据库
请求超时后 Agent 会重试。借助幂等键和异步操作,重试始终是安全的。
Agent 发出创建数据库的请求后如果网络中断,它无法判断请求是否已经成功。如果直接再发一次,最终可能得到两个数据库、两份账单,以及两套需要清理的凭证。
Lymeno API 的设计目标是让重试始终安全。本文介绍实现这一点的两个机制:幂等键和异步操作。
每个创建请求都携带幂等键
POST /v1/databases 和 DELETE /v1/databases/:id 支持 Idempotency-Key 请求头,取值为 1–255 个可打印 ASCII 字符。建议从 Agent 已有的标识(例如任务 ID)派生,这样同一任务的每次重试都会发送相同的键。
curl -X POST https://console.lymeno.com/v1/databases \
-H "Authorization: Bearer $LYMENO_TOKEN" \
-H "Idempotency-Key: task-142" \
-H "Content-Type: application/json" \
-d '{"workspaceId": "'$WORKSPACE_ID'", "regionId": "'$REGION_ID'", "name": "task-142", "productType": "serverless"}'
首次请求返回 202 Accepted,包含 operationId、databaseId 和状态 queued。再次发送相同的键时:
| 请求 | 响应 |
|---|---|
| 相同的键,相同的请求体 | 200 OK,返回原来的 operationId、databaseId 和当前状态 |
| 相同的键,相同的请求体,并发发送 | 所有请求得到同一个操作 |
| 相同的键,不同的请求体 | 409,错误码 conflict |
幂等键的作用范围是「工作区 + 接口」。因此,同一工作区内的不同 Agent 不应为不同任务复用同一个键;创建数据库时用过的键也不会影响之后的删除请求。
等待操作完成,而不是等待请求
创建、调整和删除数据库所需的时间超出了一个 HTTP 请求适合保持的时长。每项变更都是一个操作,可轮询其状态直至完成:
curl https://console.lymeno.com/v1/operations/$OPERATION_ID \
-H "Authorization: Bearer $LYMENO_TOKEN"
操作依次经过 queued、running,最终状态为 succeeded、failed 或 cancelled。响应中还会列出每个步骤及其状态和时间,Agent 可以据此报告进度,而不是默默等待。
操作成功后,获取连接信息:
curl https://console.lymeno.com/v1/databases/$DATABASE_ID/connection \
-H "Authorization: Bearer $LYMENO_TOKEN"
响应包含主机名、数据库名、端口和 sslmode: verify-full。在数据库就绪之前,主机名为 null。
重试创建角色之前先查询
创建数据库角色需要特别注意。该请求不支持幂等键,因为响应中包含角色密码,Lymeno 只返回一次且不保存明文,重放请求无法返回同一个密码。
如果 POST /v1/databases/:id/roles 请求超时,请先调用 GET /v1/databases/:id/roles。如果角色已经存在,请使用 POST /v1/databases/:id/roles/:roleId/reset-password 重置密码,而不是重新创建。
根据错误码而不是错误消息处理错误
所有错误的格式相同:
{ "error": { "code": "conflict", "message": "…", "details": { "reason": "…" } } }
code 的取值为 unauthorized、forbidden、not_found、validation_failed、conflict、payment_required 或 internal。details.reason 给出更具体的原因,例如 name_taken 或 operation_in_progress。错误消息面向人阅读,可能会调整;错误码和原因保持稳定,请基于它们编写 Agent 的重试和恢复逻辑。
一条简单的规则可以覆盖大多数情况:对于 internal 错误和网络故障,使用相同的幂等键重试;其他错误码则交由 Agent 判断如何处理。