【问题标题】:How to response with HTTP status in custom servant handler?如何在自定义服务处理程序中响应 HTTP 状态?
【发布时间】:2016-07-04 14:37:40
【问题描述】:

我创建了一个自定义服务处理程序

type ServiceSet = TVar (M.Map String [MicroService])
type LocalHandler = ReaderT ServiceSet IO

但我未能找到一种方法来在以下函数中向客户端响应 404-not-found 状态代码:

getService :: String -> LocalHandler MicroService
getService sn = do
  tvar <- ask
  ms <- liftIO $ do
    sl <- atomically $ do
      sm <- readTVar tvar
      return $ case M.lookup sn sm of
        Nothing -> []
        Just sl -> sl
    let n = length sl
    i <- randomRIO (0, n - 1)
    return $ if n == 0
      then Nothing
      else Just . head . drop i $ sl
  case ms of
    Nothing -> ??? -- throwError err404
    Just ms' -> return ms'

???如何发送404状态码?

【问题讨论】:

    标签: haskell servant


    【解决方案1】:

    您需要将ExceptT 添加到您的monad 转换堆栈中。目前,仅使用 ReaderT,无法对引发错误的概念进行编码。

    {-# LANGUAGE DataKinds     #-}
    {-# LANGUAGE TypeOperators #-}
    
    module Lib where
    
    import Control.Monad.Except
    import Control.Monad.Reader
    import Data.Maybe
    import Data.Map
    import GHC.Conc
    import Prelude hiding (lookup)
    import Servant.API
    import Servant.Server
    import System.Random
    
    type API =
      Capture "name" String :> Get '[JSON] Int
    
    type World =
      TVar (Map String [Int])
    
    type Effects =
      ExceptT ServantErr (ReaderT World IO)
    
    server :: World -> Server API
    server world =
      enter (Nat transform) get
      where
        transform :: Effects a -> ExceptT ServantErr IO a
        transform (ExceptT foo) =
          ExceptT $ runReaderT foo world
    
    get :: String -> Effects Int
    get sn = do
      tvar <- ask
      ms <- liftIO $ do
        sl <- atomically $ do
          sm <- readTVar tvar
          return (fromMaybe [] (lookup sn sm))
        let n = length sl
        i <- randomRIO (0, n - 1)
        return $ if n == 0
          then Nothing
          else Just . head . drop i $ sl
      case ms of
        Nothing ->
          throwError err404
        Just ms' ->
          return ms'
    

    使用ExceptT ServantErr . ReaderT (TVar ...),您可以使用throwError err404,Servant 将捕获并使用它来返回HTTP 404。然后,自然转换ExceptT ServantErr . ReaderT (TVar ...) :~&gt; ExceptT ServantErr 将不得不解包和重新包装以释放阅读器效果。总而言之,代码不多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-27
      • 1970-01-01
      • 2018-09-05
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多