git.iko.soy/typeable/servant
on master help sign in
add client, server and docs support for PUT
commit1181eb8d5ea523cff15cf839a457a154e33e34af authorAlp Mestanogullari <alpmestan@gmail.com> dateTue 28 Oct 2014, 09:17 (12 years ago) parent97d4133
3 files changed+68−1
servant.cabal+1 src/Servant/API.hs+3−1 src/Servant/API/Put.hs+64
servant.cabal+1
@@ -25,6 +25,7 @@ library
2525 Servant.API.Get
2626 Servant.API.GetParam
2727 Servant.API.Post
28+ Servant.API.Put
2829 Servant.API.Raw
2930 Servant.API.RQBody
3031 Servant.API.Sub
src/Servant/API.hs+3−1
@@ -4,6 +4,7 @@ module Servant.API
44 , module Servant.API.Get
55 , module Servant.API.GetParam
66 , module Servant.API.Post
7+ , module Servant.API.Put
78 , module Servant.API.RQBody
89 , module Servant.API.Sub
910 , module Servant.API.Union
@@ -14,6 +15,7 @@ import Servant.API.Delete
1415import Servant.API.Get
1516import Servant.API.GetParam
1617import Servant.API.Post
18+import Servant.API.Put
1719import Servant.API.RQBody
1820import Servant.API.Sub
19−import Servant.API.Union
21+import Servant.API.Union
src/Servant/API/Put.hsnew file+64
@@ -0,0 +1,64 @@
1+{-# LANGUAGE TypeFamilies #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
4+module Servant.API.Put where
5+
6+import Control.Monad
7+import Control.Monad.IO.Class
8+import Control.Monad.Trans.Either
9+import Data.Aeson
10+import Data.Proxy
11+import Data.String.Conversions
12+import Network.HTTP.Types
13+import Network.URI
14+import Network.Wai
15+import Servant.Client
16+import Servant.Docs
17+import Servant.Server
18+
19+import qualified Network.HTTP.Client as Client
20+
21+-- | Endpoint for PUT requests.
22+data Put a
23+
24+instance ToJSON a => HasServer (Put a) where
25+ type Server (Put a) = EitherT (Int, String) IO a
26+
27+ route Proxy action _globalPathInfo request respond
28+ | null (pathInfo request) && requestMethod request == methodPut = do
29+ e <- runEitherT action
30+ respond $ Just $ case e of
31+ Right out ->
32+ responseLBS ok200 [("Content-Type", "application/json")] (encode out)
33+ Left (status, message) ->
34+ responseLBS (mkStatus status (cs message)) [] (cs message)
35+ | otherwise = respond Nothing
36+
37+instance FromJSON a => HasClient (Put a) where
38+ type Client (Put a) = URI -> EitherT String IO a
39+
40+ clientWithRoute Proxy req uri = do
41+ partialRequest <- liftIO $ reqToRequest req uri
42+
43+ let request = partialRequest { Client.method = methodPut
44+ }
45+
46+ innerResponse <- liftIO . __withGlobalManager $ \ manager ->
47+ Client.httpLbs request manager
48+
49+ when (Client.responseStatus innerResponse /= ok200) $
50+ left ("HTTP PUT request failed with status: " ++ show (Client.responseStatus innerResponse))
51+
52+ maybe (left "HTTP PUT request returned invalid json") return $
53+ decode' (Client.responseBody innerResponse)
54+
55+instance ToSample a => HasDocs (Put a) where
56+ docsFor Proxy (endpoint, action) =
57+ single endpoint' action'
58+
59+ where endpoint' = endpoint & method .~ DocPUT
60+
61+ action' = action & response.respBody .~ toSample p
62+ & response.respStatus .~ 200
63+
64+ p = Proxy :: Proxy a