{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE CPP #-} import Data.Monoid import Servant import Servant.Generic import qualified Data.Text as T import Data.Text (Text) import Network.Wai.Handler.Warp (run) import System.Timeout import Network.URI data Site route = Site { about :: route :- "about" :> Get '[PlainText] Text , aboot :: route :- "aboot" :> Get '[PlainText] Text , faq :: route :- "faq" :> Get '[PlainText] Text , subSite :: route :- "subsite" :> ToServant (SubSite AsApi) , home :: route :- Get '[PlainText] Text } deriving Generic data SubSite route = SubSite { echo :: route :- "echo" :> Capture "x" Text :> Get '[PlainText] Text , timesTwo :: route :- "timestwo" :> Capture "x" Int :> Get '[PlainText] Text } deriving Generic type Api = ToServant (Site AsApi) subSiteServer :: SubSite AsServer subSiteServer = SubSite { echo = return , timesTwo = \x -> return $ T.pack $ show (x * 2) } siteServer :: Site AsServer siteServer = Site { about = return "about" , aboot = return ("did you mean " <> showLink (fieldLink about) <> "?") , faq = return "faq" , subSite = toServant subSiteServer , home = return "So long and thanks for all the :<|>" } main :: IO () main = do let runServer = run 31337 $ serve (Proxy :: Proxy Api) (toServant siteServer) -- just to use this example as a test, run the server for one second Nothing <- timeout 1000000 runServer return () -- Servant changed the instance of MkLink in 0.10. #if MIN_VERSION_servant(0,10,0) showLink :: Link -> Text showLink = toUrlPiece #else showLink :: URI -> Text showLink uri = T.pack (uriToString id uri "") #endif