@@ -0,0 +1,84 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE TypeFamilies #-}
3+{-# LANGUAGE DeriveGeneric #-}
4+{-# LANGUAGE TypeOperators #-}
7+import Control.Monad.Trans.Either
14+data Position = Position
17+ } deriving (Show, Generic)
19+instance FromJSON Position
20+instance ToJSON Position
22+newtype HelloMessage = HelloMessage { msg :: String }
23+ deriving (Show, Generic)
25+instance FromJSON HelloMessage
26+instance ToJSON HelloMessage
28+data ClientInfo = ClientInfo
32+ , interested_in :: [String]
33+ } deriving (Show, Generic)
35+instance FromJSON ClientInfo
36+instance ToJSON ClientInfo
43+ } deriving (Show, Generic)
45+instance FromJSON Email
48+emailForClient :: ClientInfo -> Email
49+emailForClient c = Email from' to' subject' body'
51+ where from' = "great@company.com"
53+ subject' = "Hey " ++ name c ++ ", we miss you!"
54+ body' = "Hi " ++ name c ++ ",\n\n"
55+ ++ "Since you've recently turned " ++ show (age c)
56+ ++ ", have you checked out our latest "
57+ ++ intercalate ", " (interested_in c)
58+ ++ " products? Give us a visit!"
60+type API = "position" :> Capture "x" Int :> Capture "y" Int :> Get '[JSON] Position
61+ :<|> "hello" :> QueryParam "name" String :> Get '[JSON] HelloMessage
62+ :<|> "marketing" :> ReqBody '[JSON] ClientInfo :> Post '[JSON] Email
72+ where position :: Int -> Int -> EitherT ServantErr IO Position
73+ position x y = return (Position x y)
75+ hello :: Maybe String -> EitherT ServantErr IO HelloMessage
76+ hello mname = return . HelloMessage $ case mname of
77+ Nothing -> "Hello, anonymous coward"
78+ Just n -> "Hello, " ++ n
80+ marketing :: ClientInfo -> EitherT ServantErr IO Email
81+ marketing clientinfo = return (emailForClient clientinfo)
84+app = serve api server