How do you handle file uploads in APIs?
Async APIs and webhooks: when the work takes longer than the request
Do not keep the connection open. Return 202 with a job the client can poll, or send a webhook to whoever needs to know and handle every delivery problem.
For this question · chapter 2 of 3
202 returns a job ID
- The server frees the connection after 40 ms, even though the export still needs ninety seconds. The server replies with 202 Accepted, a job id and a status URL. A 202 means the server has accepted the work, not that the work is finished. The job id and status URL give the client a way to check on the job later, not the file.
- The job has its own URL, so 202 is a normal REST answer. The client does not have to keep the connection open, so the connection closes. The job waits in the queue at /jobs/42. The work is now a resource, so the client can send a GET request to /jobs/42 at any time.
- A worker has started the job, and the job is now 18 per cent done. The worker spends the ninety seconds on the export, and the API only reports the job's status. No connection stays open while the export runs, so you can deploy the API servers and lose nothing.
- Polling has a bad reputation because some clients ask every 200 ms. Here the client asks once, with GET /jobs/42. The server answers in 38 ms and says the job is running, 61 per cent done. Each poll is tiny, and the Retry-After: 5 header lets the server decide when the client asks again.
- No connection stayed open at any point, but the client still got the answer with a second short request. The finished job returns a result URL, so the file has its own address. The API never holds a request open for a 4.1 MB file. The client fetches the file whenever it wants to.
- A job can fail long after the server returns 202, so there is no response left to put the error in. A second export fails 34 per cent of the way through. So the client fetches the job's status and reads the failure there, with an error code and a request id in the body. People who draw only the happy path, where nothing goes wrong, leave this failed state out.
The server frees the connection after 40 ms, even though the export still needs ninety seconds. The server replies with 202 Accepted, a job id and a status URL. A 202 means the server has accepted the work, not that the work is finished. The job id and status URL give the client a way to check on the job later, not the file.
© LearnThatStack - diagrams may not be republished without permission.
Want a quick review of the fundamentals? See the API Design cheatsheet.
74 of 92 API Design answers are in Pro.
Full answers, code samples, and AI explanations that go simpler or deeper. Cancel anytime.
- Full answers + code
- AI explanations, simpler or deeper
- 1,000 AI credits / month
- Cancel anytime