3. 任务接口契约设计
任务接口契约是消息队列任务系统与外部调用方之间的通信协议。本章围绕四个核心接口——任务提交、任务状态查询、任务取消和回调通知——定义其 OpenAPI 规范、请求/响应结构及错误处理链路。每个接口均遵循 RESTful 风格,使用 JSON 作为数据交换格式,并统一错误码体系。
3.1 任务提交接口定义
任务提交接口(POST /api/v1/tasks)是系统的入口点,调用方将任务描述、负载数据和调度参数发送至服务端,服务端返回任务唯一标识及初始状态。
| 属性 | 值 |
|---|---|
| HTTP 方法 | POST |
| 路径 | /api/v1/tasks |
| Content-Type | application/json |
| 成功状态码 | 201 Created |
| 失败状态码 | 400 Bad Request / 429 Too Many Requests |
请求体结构
{
"task_type": "data_export",
"payload": {
"source": "s3://bucket/input.csv",
"destination": "s3://bucket/output.parquet",
"format": "parquet"
},
"priority": 5,
"max_retries": 3,
"timeout_seconds": 3600,
"callback_url": "https://callback.example.com/notify"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_type |
string | 是 | 任务类型标识,由系统预定义 |
payload |
object | 是 | 任务执行所需的数据负载 |
priority |
integer | 否 | 优先级,1-10,默认5 |
max_retries |
integer | 否 | 最大重试次数,默认3 |
timeout_seconds |
integer | 否 | 超时时间,默认3600 |
callback_url |
string | 否 | 任务完成后的回调地址 |
响应体结构
{
"task_id": "task_20250321_001",
"status": "queued",
"created_at": "2025-03-21T10:30:00Z",
"estimated_start_at": "2025-03-21T10:30:15Z"
}
设计要点:任务提交接口应同步返回
task_id 和初始状态 queued,避免调用方长时间等待。异步执行结果通过状态查询或回调通知获取。
3.2 任务状态查询接口定义
任务状态查询接口(GET /api/v1/tasks/{task_id})允许调用方根据任务 ID 获取当前执行状态、进度和结果信息。
| 属性 | 值 |
|---|---|
| HTTP 方法 | GET |
| 路径 | /api/v1/tasks/{task_id} |
| 成功状态码 | 200 OK |
| 失败状态码 | 404 Not Found |
响应体结构
{
"task_id": "task_20250321_001",
"status": "running",
"progress": 45,
"created_at": "2025-03-21T10:30:00Z",
"started_at": "2025-03-21T10:30:16Z",
"estimated_completion_at": "2025-03-21T10:35:00Z",
"result": null,
"error": null
}
| 字段 | 类型 | 说明 |
|---|---|---|
status |
string | 当前状态:queued / running / completed / failed / cancelled |
progress |
integer | 进度百分比,0-100 |
result |
object|null | 任务完成后的结果数据 |
error |
object|null | 任务失败时的错误信息 |
注意:状态查询接口应支持轮询间隔建议(如
Retry-After 头),避免调用方高频请求导致服务压力。建议最小轮询间隔为 1 秒。
3.3 任务取消接口定义
任务取消接口(POST /api/v1/tasks/{task_id}/cancel)用于终止正在执行或等待中的任务。取消操作是幂等的,多次调用返回相同结果。
| 属性 | 值 |
|---|---|
| HTTP 方法 | POST |
| 路径 | /api/v1/tasks/{task_id}/cancel |
| 成功状态码 | 200 OK |
| 失败状态码 | 404 Not Found / 409 Conflict |
响应体结构
{
"task_id": "task_20250321_001",
"status": "cancelled",
"cancelled_at": "2025-03-21T10:32:00Z",
"message": "Task cancelled by user request"
}
幂等性保证:如果任务已经处于
completed 或 failed 状态,取消接口应返回 409 Conflict,并在响应体中说明当前状态不允许取消。
3.4 回调通知接口定义
回调通知接口由服务端主动调用,在任务状态发生变化时通知调用方。调用方需在任务提交时提供 callback_url,服务端在任务完成、失败或取消时发送 POST 请求。
| 属性 | 值 |
|---|---|
| HTTP 方法 | POST |
| Content-Type | application/json |
| 期望响应 | 200 OK 或 204 No Content |
| 重试策略 | 最多 3 次,间隔 5s、30s、120s |
回调请求体结构
{
"task_id": "task_20250321_001",
"event": "completed",
"timestamp": "2025-03-21T10:35:00Z",
"result": {
"output_path": "s3://bucket/output.parquet",
"row_count": 150000
},
"error": null
}
| 字段 | 类型 | 说明 |
|---|---|---|
event |
string | 事件类型:completed / failed / cancelled |
timestamp |
string | 事件发生时间(ISO 8601) |
result |
object|null | 任务结果(仅 completed 时存在) |
error |
object|null | 错误信息(仅 failed 时存在) |
可靠性设计:回调通知应支持签名验证(如 HMAC-SHA256),防止伪造回调。调用方应在收到回调后立即返回 2xx,避免服务端重试导致重复处理。
3.5 接口关系与数据流
下图展示了四个接口之间的调用关系和数据流向,帮助理解任务从提交到完成的完整生命周期。
3.6 统一错误码与错误响应结构
所有接口使用统一的错误响应格式,便于调用方解析和处理异常情况。
错误响应体结构
{
"error": {
"code": "TASK_NOT_FOUND",
"message": "Task with ID 'task_20250321_999' not found",
"details": {
"task_id": "task_20250321_999",
"suggestion": "Verify the task ID and retry"
}
}
}
| HTTP 状态码 | 错误码 | 说明 |
|---|---|---|
| 400 | INVALID_PAYLOAD |
请求体格式错误或必填字段缺失 |
| 404 | TASK_NOT_FOUND |
任务 ID 不存在 |
| 409 | TASK_NOT_CANCELLABLE |
任务当前状态不允许取消 |
| 429 | RATE_LIMIT_EXCEEDED |
请求频率超过限制 |
| 500 | INTERNAL_ERROR |
服务端内部错误 |
错误处理最佳实践:调用方应根据
code 字段进行分支处理,而非依赖 HTTP 状态码。例如 TASK_NOT_FOUND 应触发重试或告警,而 RATE_LIMIT_EXCEEDED 应等待后重试。
3.7 接口契约校验清单
以下清单帮助开发者在实现接口时逐项检查,确保契约完整性和一致性。
- 请求校验:所有必填字段是否在 OpenAPI 规范中标记为
required? - 响应一致性:成功和失败响应是否使用统一的结构模板?
- 幂等性:取消接口和状态查询接口是否幂等?
- 超时处理:任务提交接口是否设置了合理的超时时间?
- 回调安全:回调通知是否包含签名验证机制?
- 错误码覆盖:所有可能的异常场景是否都有对应的错误码?
- 文档同步:OpenAPI 规范是否与实现代码保持同步更新?
契约驱动开发:建议使用 OpenAPI 规范作为单一事实来源,通过代码生成工具自动生成服务端和客户端代码,减少手动实现带来的不一致风险。