Description
A value level web framework.
Description
A value level web framework in the style of servant
README.md
Eved - A Value Level Servant Replacement
Eved is an API definition eDSL in the spirit of Servant. The main difference from Servant is that Eved is a value level API, whereas Servant relies very heavily on fancy type level programming.
Eved is highly extensible (both in terms of implementations and new terms) thanks to its utilization of the so called final tagless
encoding.
Example
Api Definition
import Data.Text (Text)
import Web.Eved
import qualified Web.Eved.ContentType as CT
import qualified Web.Eved.QueryParam as QP
import qualified Web.Eved.UrlElement as UE
type Api m =
(Integer -> Integer -> m Integer)
:<|> (Text -> Integer -> m Integer)
:<|> (Text -> Integer -> m Integer)
api :: Eved api m => api (Api m)
api =
(lit "v1" .</> capture "captureNum" UE.integer .</> queryParam "arg1" QP.integer .</> get [CT.json @Integer])
.<|> (lit "v1" .</> capture "captureText" UE.text .</> reqBody [CT.json @Integer] .</> post [CT.json @Integer])
.<|> (lit "v2" .</> capture "captureText" UE.text .</> queryParam "arg1" QP.integer .</> get [CT.json @Integer])
Client
import Web.Eved.Client
v1CaptureNum :<|> v1CaptureText :<|> v2CaptureText = getClient api "http://localhost:3000"
Server
import Control.Monad.IO.Class
import Control.Monad.Reader
import Web.Eved.Server
import Network.Wai.Handler.Warp
serve :: IO ()
serve = run 3000 $ server (`runReaderT` (Env 100)) handlers api
data Env = Env
{ envSecret :: Integer
}
handlers :: (MonadIO m, MonadReader Env m) => Api m
handlers = (\a b -> pure $ a + b)
:<|> (\_ i -> fmap ((+) i) (asks envSecret))
:<|> (\_ i -> pure i)
Prior Art
TODO
How to extend the language
TODO.