非同步 API 的設計

阮一峰發表於2018-12-12

網站的前後端通訊,往往會有非同步請求,這時應該怎麼設計 API?

我最近讀到一篇文章,作者介紹了他的做法,設計得很精細,我覺得值得借鑑,可以當作非同步 API 的標準設計。

一、同步 API

為了便於比較,先看看同步 API 的設計。下面是一個很簡單的例子。

客戶端發出一個請求,要求建立資源。


POST https://api.service.io/stars

name='Death Star' 

伺服器回應 201。


HTTP/1.1 201 Created
Location: /stars/12345

201 Created告訴客戶端,請求成功,資源已經建立。新的資源的網址請看Location欄位。

二、非同步請求

如果伺服器不能立即返回結果,就形成了非同步操作。

客戶端的請求還是一樣的。


POST https://api.service.io/stars

name='Death Star' 

伺服器回應 202。


HTTP/1.1 202 Accepted
Location: /queue/12345

202 Accepted告訴客戶端,請求已經接受,但還沒有處理,可以去Location欄位查詢進展。

除了上面的頭資訊,伺服器的回應如果有資料體,可以返回一些有效資訊(比如任務完成的估計時間、當前狀態等等)。

三、查詢進展

過了一段時間,客戶端就發出請求,查詢非同步處理的進展。


GET https://api.service.io/queue/12345 

伺服器回應 200。


HTTP/1.1 200 Ok  

<response>
 <status>PENDING</status>
  <eta>2 mins.</eta>
  <link rel="cancel" method="delete" href="/queue/12345" /> 
</response>

200 Ok告訴客戶端,請求成功,具體情況檢視資料體。資料體裡給出提示,非同步操作已成功或還需要等待。

四、非同步操作成功

有一種特殊情況,使用者查詢非同步操作的進展的時候,可能會希望,如果非同步操作已經完成,就直接跳轉到新資源。

這時,伺服器回應 303。


HTTP/1.1 303 See Other 
Location: /stars/97865

303 see other告訴客戶端,重定向到不同的資源。Location欄位就是跳轉的目標,也就是新資源的網址。

五、刪除查詢連結

一旦非同步操作完成,客戶端可以要求伺服器刪除查詢連結。


DELETE https://api.service.io/queue/12345 

伺服器回應 204。


HTTP/1.1 204 No Content

204 No Content告訴客戶端,刪除成功。以後,客戶端再訪問這個查詢連結,伺服器回應404 Not Found

如果客戶端不刪除查詢連結,伺服器完成非同步任務後,也可以自動刪除。客戶端再請求這個連結,伺服器回應410 Gone,表示該連結永久性不再可用。

(完)

相關文章