on c2be4f3 help sign in
56 lines 1.8 kB history raw
1{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE DeriveDataTypeable #-}
5module Servant.API.Post where
7import Control.Monad.Trans.Either
8import Data.Aeson
9import Data.Proxy
10import Data.String.Conversions
11import Data.Typeable
12import Network.HTTP.Types
13import Network.URI
14import Network.Wai
15import Servant.Client
16import Servant.Docs
17import Servant.Server
18import Servant.Utils.Client
20-- | Endpoint for POST requests. The type variable represents the type of the
21-- response body (not the request body, use 'Servant.API.RQBody.RQBody' for
22-- that).
23data Post a
24 deriving Typeable
26instance ToJSON a => HasServer (Post a) where
27 type Server (Post a) = EitherT (Int, String) IO a
29 route Proxy action request respond
30 | null (pathInfo request) && requestMethod request == methodPost = do
31 e <- runEitherT action
32 respond . succeedWith $ case e of
33 Right out ->
34 responseLBS status201 [("Content-Type", "application/json")] (encode out)
35 Left (status, message) ->
36 responseLBS (mkStatus status (cs message)) [] (cs message)
37 | null (pathInfo request) && requestMethod request /= methodPost =
38 respond $ failWith WrongMethod
39 | otherwise = respond $ failWith NotFound
41instance FromJSON a => HasClient (Post a) where
42 type Client (Post a) = URIAuth -> EitherT String IO a
44 clientWithRoute Proxy req uri =
45 performRequest methodPost req 201 uri
47instance ToSample a => HasDocs (Post a) where
48 docsFor Proxy (endpoint, action) =
49 single endpoint' action'
51 where endpoint' = endpoint & method .~ DocPOST
53 action' = action & response.respBody .~ toSample p
54 & response.respStatus .~ 201
56 p = Proxy :: Proxy a