blob: 292168741bb57a7ae42c42b07d1727f7fab0d1e3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
module RestService (start) where
import Network.HTTP.Types.URI
import Network.Wai
import Network.Wai.Handler.Warp
import Data.Aeson (FromJSON, ToJSON)
import Web.Scotty as S
import Data.Maybe (fromMaybe)
import GHC.Generics
import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TArray
import qualified BizExpr as E
import qualified Data.Text.Lazy as L
import qualified Data.Text as T
import qualified Data.Map as M
import qualified Network.HTTP.Types.Status as Status
staticFilePaths :: [FilePath]
staticFilePaths = map ("./static/" ++) ["materialize.min.css", "materialize.min.js", "service.js"]
staticFiles :: ScottyM ()
staticFiles = do
-- get "/static/:file" $ file
mapM_ addFile staticFilePaths
where
addFile path = get (capture $ tail path) $ file path
data ExprReq = ExprReq {expression :: L.Text, result :: Maybe L.Text}
deriving (Show, Generic)
instance FromJSON ExprReq
numInc :: State -> IO Int
numInc s = atomically (readTVar s >>= writeTVar s . (+1) >> readTVar s)
routes :: State -> ScottyM ()
routes state = do
staticFiles
get "/num" $
S.json =<< liftAndCatchIO (numInc state)
get "/:expr" $
S.text =<< S.param "expr"
post "/eval" $
S.text . L.pack . fromMaybe "failure" . E.eval . L.unpack . expression =<< S.jsonData
type State = TVar Int
start :: IO ()
start = scottyOpts opts . routes =<< newTVarIO 3
opts :: Options
opts = Options 1 settings
where
settings = setPort 3000 defaultSettings
|