在Servant中发送通用内容类型

Eco*_*ium 7 haskell servant

我试图将一些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

更新:我已经开了一个问题

use*_*650 4

这是可能的,但有点黑客:

{-# 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鉴于此,您可能希望在存储库中提出有关此问题的问题以获得更完整的支持。