我制作了一个自定义组合器:MultipartUpload
,但是当我使用它时,它最终不仅应用了我使用它的路线,还应用了所有后续路线:
例如,在以下 API 中,MultipartUpload
在第 2 条和第 3 条路线上运行。因此,如果我调用第三个,它将返回错误File upload required
。我只希望它适用于第二个。如何?
type ModelAPI =
"models" :>
( ProjectKey :> Get '[JSON] [Model]
:<|> ProjectKey :> MultipartUpload :> Post '[JSON] Model
:<|> ProjectKey :> Capture "modelId" ID :> Get '[JSON] Model
)
这是如何MultipartUpload
定义的。
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Servant.Multipart
( MultipartUpload
, FileInfo(..)
) where
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as Lazy
import Network.HTTP.Types (status400)
import Network.Wai.Parse
import Network.Wai (responseLBS)
import Servant
import Servant.Server.Internal
data MultipartUpload
instance (HasServer sublayout) => HasServer (MultipartUpload :> sublayout) where
type ServerT (MultipartUpload :> sublayout) m =
FileInfo ByteString -> ServerT sublayout m
route Proxy subserver req respond = do
dat <- parseRequestBody lbsBackEnd req
let files = snd dat
case files of
[(_, f)] ->
if Lazy.null $ fileContent f
then respond . succeedWith $ responseLBS status400 [] "Empty file"
else route (Proxy :: Proxy sublayout) (subserver f) req respond
[] ->
respond . succeedWith $ responseLBS status400 [] "File upload required"
_ ->
respond . succeedWith $ responseLBS status400 [] "At most one file allowed"