2016-01-24 55 views
6

我正在嘗試向我的servant服務器添加功能,該服務器將從Amazon S3獲取文件並將其傳回給用戶。 由於文件可能很大,我不想在本地下載它們,然後將它們提供給客戶端,我寧願將它們直接從S3傳輸到客戶端。Haskell僕人和流式傳輸

我使用Amazonka來處理S3的工作,我可以得到一個S3文件流作爲Conduit接收器。

但是現在我不知道如何從SinkEitherT ServantErr IO a

任何人都可以解釋我如何做到這一點或向我展示如何做到這一點的例子嗎?

+0

目前僕人中有一名PR加入「Stream端點支持」。 https://github.com/haskell-servant/servant/pull/836 – erewok

回答

4

僕人沒有這個開箱即用,但所有需要的部分都可用。

在我們開始之前,我想,如果你能流到水槽,這意味着你有一個源(的GetObjectResponsegorsBodyRsBody,這是一個Source)

首先,僕人爲我們提供可以通過創建一個新的實例HasServer來添加對新的返回類型的支持,所以我們可以提供一個EitherT ServantErr IO (Source ...)並使其流。

要創建該實例,我們必須實現route :: Proxy layout -> Server layout -> RoutingApplicationServer layout,在這種情況下,這意味着EitherT ServantErr IO layout,layout是我們想要的服務器的源,所以它是返回源的函數(並且可能會因爲HTTP錯誤而失敗)。

我們必須返回一個RoutingApplication,這是(在延續的風格),一個函數,一個Request並返回一個RouteResult Response,這意味着無論是無以倫比的路線錯誤,或響應。 RequestResponse都是標準的wai,而不是僕人,所以我們現在可以查看生態系統的其他部分,以瞭解如何實施它。

幸運的是,我們沒有走得很遠:Network.Wai.Conduit包含正是我們需要實現route功能:responseSource需要一個狀態值,一些響應頭和源,給你一個Response

所以,這是相當多的工作要做,但我們需要的一切都在那裏。尋找source of the instance HasServer * (Get ...)可能會有所幫助。

+0

我想添加一個解釋/參考如何在WAI層面做到這一點是很好的,以瞭解如何適應僕人級別。對於我來說,不清楚什麼會消耗「路線」返回的內容,以及如何思考延續風格設置。 – user239558