§Play HTTP API 簡介
§什麼是 EssentialAction?
EssentialAction
是 Play 的 HTTP API 使用的基本函數類型。這與 Java 中的 Action
類型不同,後者是一種接受 Request
並傳回 CompletionStage<Result>
的較高層級類型。在 Java 應用程式中,大多時候你不需要直接使用 EssentialAction
,但當撰寫篩選器或與其他低層級 Play API 互動時,它會很有用。
要瞭解 EssentialAction
,我們需要瞭解 Play 架構。
Play 的核心很小,周圍環繞著大量有用的 API、服務和結構,讓 Web 程式設計任務更輕鬆。
基本上,Play 的動作 API 抽象具有下列類型
RequestHeader -> byte[] -> Result
上述類型會取得要求標頭 RequestHeader
,然後將要求主體當成 byte[]
取得,並產生一個 Result
。
現在,這個類型假設將要求主體全部放入記憶體(或磁碟)中,即使你只想從中計算一個值,或最好將它轉發到 Amazon S3 等儲存服務。
我們比較想將要求主體區塊接收為串流,並在必要時能夠逐步處理它們。
我們需要變更第二個箭頭,讓它接收區塊中的輸入,並最終產生一個結果。有一個類型可以做到這一點,它稱為 Accumulator
,並採用兩個類型參數。
Accumulator<E,R>
是一種 箭頭 類型,它會以 E
類型的區塊取得輸入,並最終傳回 R
。對於我們的 API,我們需要一個 Accumulator,它取得 ByteString
區塊(基本上是位元組陣列的更有效率包裝器),並最終傳回一個 Result
。因此,我們稍微修改類型為
RequestHeader -> Accumulator<ByteString, Result>
最後,我們的 Java 類型看起來像
Function<RequestHeader, Accumulator<ByteString, Result>>
這應該讀作:取得要求標頭,取得代表要求主體的 ByteString
區塊,並最終傳回一個 Result
。這正是 EssentialAction
的 apply 方法定義的方式
public abstract Accumulator<ByteString, Result> apply(RequestHeader requestHeader);
另一方面,Result
類型可以抽象地視為回應標頭和回應主體
Result(ResponseHeader header, ByteString body)
但是,如果我們想要逐步將回應主體傳送給客戶端,而不用將其全部填入記憶體中,該怎麼辦?我們需要改善我們的類型。我們需要將主體類型從 ByteString
替換為產生 ByteString
塊的類型。
我們已經有了一個類型,稱為 Source<E, ?>
,這表示它能夠產生 E
的塊,在我們的案例中是 Source<ByteString, ?>
Result(ResponseHeader header, Source<ByteString, ?> body)
如果我們不必逐步傳送回應,我們仍然可以將整個主體作為一個塊傳送。在實際的 API 中,Play 使用 HttpEntity
包裝類型支援不同的實體類型,它支援串流、分塊和嚴格實體。
§結論
必要的 Play HTTP API 非常簡單
RequestHeader -> Accumulator<ByteString, Result>
讀起來如下:取得 RequestHeader
,然後取得 ByteString
塊,並傳回回應。回應包含 ResponseHeaders
和一個主體,它是可轉換為 ByteString
的值塊,以寫入表示在 Source<E, ?>
類型中的 socket。
下一頁:HTTP 篩選器
在這個文件中發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提交 pull request。有問題或建議要分享嗎?前往 我們的社群論壇 與社群展開對話。