Haskell Servant and Streaming

I am trying to add functionality to my servant server, which will receive a file from Amazon S3 and transfer it back to the user. Since files can be large, I don’t want to download them locally and then send them to clients, I prefer to transfer them directly from S3 to clients.

I use Amazonka for what I do with S3, and I can get the stream for the S3 file as a Conduit shell.

But now I don’t know how to get from Sink to EitherT ServantErr IO a .

Can someone explain to me how to do this or show me an example of how this can be done?

+7
haskell amazon-s3 servant
source share
2 answers

Nothing is done in the Servant, so all the necessary parts are available.

Before we begin, I assume that if you can pass to a stream in Sink, it means that you have a source ( gorsBody GetObjectResponse is RsBody , which is the source)

First of all, Servant provides us with the ability to add support for new return types by creating a new instance of HasServer , so we could serve the EitherT ServantErr IO (Source ...) and have a stream.

To create this instance, we must implement route :: Proxy layout -> Server layout -> RoutingApplication . Server layout , in this case, simply means EitherT ServantErr IO layout , layout , which is the source that we want to use for the server, so it returns a function that returns the source (and may fail with an HTTP error).

We must return a RoutingApplication , which is (in the continuation style) a function that accepts a Request and returns a RouteResult Response , which means either an unsurpassed route error or a response. Both Request and Response are standard wai, not Servant, so now we can look at the rest of the ecosystem to find how to implement it.

Fortunately, we don’t have to go far: Network.Wai.Conduit contains only what we need to implement the route function: responseSource takes a status value, some response headers and your source and gives you a Response .

So this is quite a bit of work, but all we need is there. Finding the source of the HasServer * (Get ...) instance can help.

+4
source share

Just to update this search engine friendly question: Servant now supports the Stream module .

0
source share

All Articles