我试图将一些ByteString回传给客户端(浏览器).客户端将不知道所请求文档的内容类型,因此我尝试将适当的内容类型响应发送回客户端.该文件可以是图像或pdf或word文档等.
例如,客户端将请求/document?id=55并且服务器将使用适当的内容类型和关联的内容进行响应ByteString.
我按照这里的例子:我为图像创建了一些东西.
data IMAGE
instance Accept IMAGE where
contentType _ = "image" M.// "jpeg"
instance MimeRender IMAGE LBS.ByteString where
mimeRender _ = id
Run Code Online (Sandbox Code Playgroud)
挑战是客户端不会发送带有某些特定Accept:标头的请求,因此我无法像在此处所做的那样对适当的Mime类型做出反应.加上上面将只图像工作(假设浏览器将推断png,即使我发回jpeg),但不适合pdf,docx等.
我想过一个类似于paramaterized的类型MyDynamicContent String,我会在运行时传入内容类型,但我不确定如何声明我的API,即我将使用什么代替'[JSON].不确定这样的事情是否可能,因为示例只是一个简单的数据类型.
所以我的问题是,如果我想发送一些ByteString作为响应并Content-Type动态设置标题,那么使用它的最佳方法是什么servant
更新:我已经开了一个问题
这是可能的,但有点黑客:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverlappingInstances #-}
module DynCT where
import Control.Monad.Trans.Either
import Data.ByteString.Lazy (ByteString)
import Servant
import Servant.API.ContentTypes
import Network.Wai.Handler.Warp
data WithCT = WithCT { header :: ByteString, content :: ByteString }
instance AllCTRender xs WithCT where
handleAcceptH _ _ (WithCT h c) = Just (h, c)
type API = Get '[] WithCT
api :: Proxy API
api = Proxy
server :: Server API
server = return $ WithCT { header = "example", content = "somecontent" }
main :: IO ()
main = run 8000 $ serve api server
Run Code Online (Sandbox Code Playgroud)
测试它:
% curl localhost:8000 -v
...
< HTTP/1.1 200 OK
...
< Content-Type: example
<
...
somecontent%
Run Code Online (Sandbox Code Playgroud)
这个想法只是通过声明 的重叠实例来覆盖正常行为AllCTRender。请注意,如果您也使用这些servant-client,您可能还需要为 等做一些额外的腿部工作。servant-docs鉴于此,您可能希望在存储库中提出有关此问题的问题以获得更完整的支持。