我正在尝试向我的servant服务器添加一个功能,该功能将从亚马逊S3获取文件,并将其流回给用户。因为文件可能很大,我不想在本地下载它们,然后将它们提供给客户端,我更喜欢直接从S3将它们流式传输到客户端。
我将Amazonka用于我对S3所做的工作,并且我可以获得S3文件的流作为Conduit接收器。
但是现在我不知道如何从Sink到EitherT ServantErr IO a。
有没有人能给我解释一下怎么做,或者给我举个例子?
发布于 2016-01-25 18:44:39
没有任何现成的服务可以做到这一点,但是所有需要的部件都是可用的。
在我们开始之前,我猜如果你可以流到一个接收器,这意味着你有一个源( GetObjectResponse的gorsBody是一个RsBody,这是一个源)
首先,Servant为我们提供了添加对新返回类型的支持的可能性,方法是创建一个新的HasServer实例,这样我们就可以为EitherT ServantErr IO (Source ...)提供服务并使其成为流。
要创建该实例,我们必须实现route :: Proxy layout -> Server layout -> RoutingApplication。在本例中,Server layout只表示EitherT ServantErr IO layout,layout是我们想要的源,所以它是返回源的函数(可能会失败并返回HTTP错误)。
我们必须返回一个RoutingApplication,这是一个(以延续方式)接受Request并返回RouteResult Response的函数,这意味着不匹配的路由错误或响应。Request和Response都是标准的wai,而不是Servant,所以我们现在可以看看生态系统的其余部分,以找到如何实现它。
幸运的是,我们不必走得太远:Network.Wai.Conduit包含我们实现route函数所需的内容:responseSource接受一个状态值、一些响应头和您的源,并为您提供一个Response。
因此,这是相当多的工作要做,但我们需要的一切都在那里。查看一下source of the instance HasServer * (Get ...)可能会有所帮助。
https://stackoverflow.com/questions/34974257
复制相似问题