如何在Yesod中编写接收文件/图像上传的JSON端点?
我看到很多帖子都涉及编写表单小部件来处理图像上传,但我的YesSOD服务器只是一个JSON API。我将通过Angular File Upload接收Post请求。一种简单的方法是将文件编码为base64数据,然后 然后将其作为JSON的一部分发送。但这种方法的缺点是 它增加了数据的大小 例如:如何在Yesod中编写接收文件/图像上传的JSON端点?,json,ajax,haskell,file-upload,yesod,Json,Ajax,Haskell,File Upload,Yesod,我看到很多帖子都涉及编写表单小部件来处理图像上传,但我的YesSOD服务器只是一个JSON API。我将通过Angular File Upload接收Post请求。一种简单的方法是将文件编码为base64数据,然后 然后将其作为JSON的一部分发送。但这种方法的缺点是 它增加了数据的大小 例如: #!/usr/bin/env stack {- stack --resolver lts-6.24 --install-ghc runghc --package
#!/usr/bin/env stack
{- stack
--resolver lts-6.24
--install-ghc
runghc
--package yesod
--package yesod-core
--package persistent
--package text
--package aeson
--package bytestring
--package base64-bytestring
-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances#-}
{-# LANGUAGE OverloadedStrings#-}
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad (join)
import Control.Applicative
import Data.Text (Text, unpack)
import qualified Data.Text.Lazy.Encoding
import Data.Typeable (Typeable)
import Text.Blaze.Html.Renderer.Utf8 (renderHtml)
import Yesod
import Data.Aeson
import Data.Aeson.Types
import qualified Data.ByteString as BS
import Data.ByteString (ByteString)
import qualified Data.ByteString.Base64 as BS
import qualified Data.Text.Encoding as T
data App = App
mkYesod
"App"
[parseRoutes|
/json/test TestR POST
|]
instance Yesod App where
approot = ApprootStatic "http://localhost:3006"
instance RenderMessage App FormMessage where
renderMessage _ _ = defaultFormMessage
data Test = Test {
fileData :: Text,
name :: String
} deriving (Show, Eq, Ord)
instance FromJSON Test where
parseJSON (Object v) = Test <$>
v .: "fileData" <*>
v .: "name"
parseJSON _ = empty
postTestR :: Handler TypedContent
postTestR = do
testData :: Test <- requireJsonBody
let fileData' = BS.decode (T.encodeUtf8 $ fileData testData)
case fileData' of
Left err -> error err
Right dat -> liftIO $ BS.writeFile "/home/sibi/myfile" dat
selectRep $ provideRep $ return emptyObject
main :: IO ()
main = warp 3006 App
$ curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"fileData":"aGVsbG8gd29ybGQ=","name":"Filename"}' http://127.0.0.1:3006/json/test
$ cat /home/sibi/myfile
hello world