I’m trying to implement this POST request
curl -F "file=@test.txt" https://api.anonfiles.com/upload
in Servant but kind a lost can anybody help ?
The first step would be to define your API as a type!
Then implement a server implementation for the API (the type you defined for it)
Then serve that server implementation using Warp’s run
Where are you stuck?
Hi,
here is a small program that should help you get started:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Control.Monad (forM_)
import Control.Monad.IO.Class (MonadIO (liftIO))
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text as Text
import qualified Network.Wai.Handler.Warp as Warp
import Servant (JSON, Post, Proxy (..), Server, type (:>))
import qualified Servant
import Servant.Multipart
( Mem,
MultipartData,
MultipartForm,
)
import qualified Servant.Multipart as SMP
main :: IO ()
main = do
putStrLn "Servant-Upload - try uploading to http://localhost:8080/upload - you should find the file in ./upload"
startServer
type API = "upload" :> MultipartForm Mem (MultipartData Mem) :> Post '[JSON] Integer
startServer :: IO ()
startServer = Warp.run 8080 (Servant.serve (Proxy :: Proxy API) upload)
upload :: Server API
upload multipartData = liftIO $ do
forM_ (SMP.files multipartData) $ \file -> do
let content = SMP.fdPayload file
LBS.writeFile ("./upload/" ++ Text.unpack (SMP.fdFileName file)) content
putStrLn $ "received file " ++ Text.unpack (SMP.fdFileName file)
return 0
in order to compile this you need some dependencies - you should add this to the dependency-section of your .cabal
file:
build-depends: base ^>=4.16.0.0,
bytestring ^>= 0.11,
servant ^>= 0.19,
servant-multipart ^>= 0.12,
servant-server ^>= 0.19,
text ^>= 1.2,
warp ^>= 3.3
(versions should be ok for now but might vary - if in doubt look at the documentation of those libraries)
Before starting this (for example with cabal run
) you should create a upload
-folder (for example mkdir upload
) as the program will put the uploaded files there and will panic if the path ./upload/[uploadedfilename]
is not valid )
Then something like curl -F "file=@CHANGELOG.md" http://localhost:8080/upload
should upload the file and you should see it in the upload folder together with a message saying so.
For more details there is a servant cookbook entry on File Upload here and you should find plenty of information in the servant docs in general.
Of course feel free to ask for more details.
Have fun.