servant/src/Servant/API/Get.hs

46 lines
1.6 KiB
Haskell
Raw Normal View History

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-}
module Servant.API.Get where
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Either
import Data.Aeson
import Data.Proxy
import Data.String.Conversions
import Network.HTTP.Types
import Network.URI
import Network.Wai
import Servant.Client
import Servant.Server
import qualified Network.HTTP.Client as Client
-- | Endpoint for simple GET requests. The server doesn't receive any arguments
-- and serves the contained type as JSON.
data Get a
instance ToJSON result => HasServer (Get result) where
type Server (Get result) = EitherT (Int, String) IO result
route Proxy action _globalPathInfo request respond
| null (pathInfo request) && requestMethod request == methodGet = do
e <- runEitherT action
respond $ Just $ case e of
Right output ->
responseLBS ok200 [("Content-Type", "application/json")] (encode output)
Left (status, message) ->
responseLBS (mkStatus status (cs message)) [] (cs message)
| otherwise = respond Nothing
instance FromJSON result => HasClient (Get result) where
type Client (Get result) = URI -> EitherT String IO result
clientWithRoute Proxy req uri = do
innerRequest <- liftIO $ reqToRequest req uri
innerResponse <- liftIO $ __withGlobalManager $ \ manager ->
Client.httpLbs innerRequest manager
when (Client.responseStatus innerResponse /= ok200) $
left ("HTTP GET request failed with status: " ++ show (Client.responseStatus innerResponse))
maybe (left "HTTP GET request returned invalid json") return $
decode' (Client.responseBody innerResponse)