Created
June 26, 2015 18:07
-
-
Save anonymous/a99bc6b36ac2db64878e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE EmptyDataDecls #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE GeneralizedNewtypeDeriving #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE QuasiQuotes #-} | |
{-# LANGUAGE TemplateHaskell #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE RecordWildCards #-} | |
{-# LANGUAGE DeriveGeneric #-} | |
module Main where | |
import Network.Wai.Handler.Warp (run) | |
import System.Environment (lookupEnv) | |
import Database.Persist.Sql (runSqlPool) | |
import Control.Monad.Reader (ReaderT, runReaderT, lift) | |
import Control.Monad.Trans.Either (EitherT, left) | |
import Network.Wai (Application) | |
import Servant | |
import qualified Servant.Utils.StaticFiles as S | |
import Database.Persist.Sqlite (ConnectionPool, createSqlitePool) | |
import Data.Aeson (ToJSON, FromJSON) | |
import GHC.Generics (Generic) | |
data Config = Config { getPool :: ConnectionPool , getEnv :: Environment } | |
defaultConfig :: Config | |
defaultConfig = Config { getPool = undefined , getEnv = Development } | |
data Environment = Development | Test | Production deriving (Eq, Show, Read) | |
data Person = Person { name :: String , email :: String } deriving (Eq, Show, Generic) | |
instance ToJSON Person | |
instance FromJSON Person | |
type PersonAPI = | |
"users" :> Capture "name" String :> Get '[JSON] Person | |
:<|> "static" :> Raw | |
type AppM = ReaderT Config (EitherT ServantErr IO) | |
userAPI :: Proxy PersonAPI | |
userAPI = Proxy | |
app :: Config -> Application | |
app cfg = serve userAPI (readerServer cfg) | |
readerServer :: Config -> Server PersonAPI | |
readerServer cfg = enter (readerToEither cfg) server | |
readerToEither :: Config -> AppM :~> EitherT ServantErr IO | |
readerToEither cfg = Nat $ \x -> runReaderT x cfg | |
server :: ServerT PersonAPI AppM | |
server = singlePerson :<|> S.serveDirectory "/static" | |
singlePerson :: String -> AppM Person | |
singlePerson str = do | |
let person = Person { name = "Joe", email = "joe@example.com" } | |
return person | |
main :: IO () | |
main = do | |
let cfg = defaultConfig | |
run 8081 $ app cfg |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This should work just fine (basically keep the non
Raw
endpoints in a type, use enter on it, and then stick the file serving handler next to the result ofenter
):