Implementing Long-Running Operations
1. Returning 202 Accepted
Example: 202 with Operation Location
POST /reports HTTP/1.1
Content-Type: application/json
{"type": "annual", "year": 2025}
HTTP/1.1 202 Accepted
Location: /operations/abc-123
Content-Type: application/json
{
"id": "abc-123",
"status": "queued",
"links": {"self": "/operations/abc-123"}
}
2. Providing Operation Status Endpoint
| Endpoint | Purpose |
|---|---|
GET /operations/{id} | Current status + progress |
DELETE /operations/{id} | Cancel operation |
GET /operations/{id}/result | Final result (when status=completed) |
3. Using Polling for Status Updates
| Strategy | Notes |
|---|---|
| Fixed interval | Simple; wasteful for slow ops |
| Exponential backoff | Start 1s, double up to 60s |
| Server-suggested | Retry-After in 202/200 response |
4. Implementing Callback URLs
Example: Webhook Callback Registration
POST /reports
{
"type": "annual",
"callbackUrl": "https://client.example.com/hooks/report-done",
"callbackSecret": "shared-secret"
}
5. Using WebSockets for Real-Time Updates
| Property | Notes |
|---|---|
| Bidirectional | Server → client push, client → server messages |
| Persistent connection | Single TCP, low overhead per message |
| Use case | Chat, live dashboards, collaborative editing |
| Auth | Token in connection URL or first message |
6. Using Server-Sent Events
| Property | Notes |
|---|---|
| Direction | Server → client only |
| Content-Type | text/event-stream |
| Auto-reconnect | Built into EventSource API |
| Last-Event-ID | Resume from last received event |
| Use case | Notifications, progress, log tailing |
Example: SSE Stream
id: 1
event: progress
data: {"percent": 25}
id: 2
event: progress
data: {"percent": 50}
id: 3
event: completed
data: {"resultUrl": "/reports/123"}
7. Implementing Operation Cancellation
| Method | URI |
|---|---|
DELETE /operations/{id} | Standard cancel |
POST /operations/{id}/cancel | Action-style |
| Status after | cancelling → cancelled |
8. Providing Progress Information
| Field | Type |
|---|---|
status | queued, running, completed, failed, cancelled |
progress | 0.0 - 1.0 |
currentStep / totalSteps | Multi-stage ops |
message | Human-readable detail |
startedAt / etaSeconds | Timing info |
9. Handling Operation Expiration
| Event | Behavior |
|---|---|
| Result expires | 410 Gone with retention policy |
| Status record TTL | Keep 7-30 days |
| Generated artifacts | Pre-signed URL with expiry |
10. Returning Final Result Location
| Field | Example |
|---|---|
resultUrl | URL to download/view result |
Location header | On final completion redirect |
| Embedded result | For small results, inline in status response |