Organize application logic by core/feature breakouts, add dhall configuration support and add a range of new config options in the Reader, add example configuration/deployment files
This commit is contained in:
parent
b4d6e9c9d1
commit
f7a61dcddc
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.stack-work
|
||||||
|
data/
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,4 +1,7 @@
|
|||||||
|
data/
|
||||||
|
bin/
|
||||||
|
/config.dhall
|
||||||
|
/Dockerfile
|
||||||
|
docker-stack.yml
|
||||||
.stack-work/
|
.stack-work/
|
||||||
./data
|
|
||||||
./config.dhall
|
|
||||||
*~
|
*~
|
||||||
|
75
Purr.cabal
75
Purr.cabal
@ -19,13 +19,38 @@ extra-source-files:
|
|||||||
|
|
||||||
library
|
library
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
|
Core.Configuration
|
||||||
|
Core.HTTP
|
||||||
|
Core.Mongo
|
||||||
|
Core.Types
|
||||||
|
Feature.Handlers
|
||||||
Lib
|
Lib
|
||||||
other-modules:
|
other-modules:
|
||||||
Paths_Purr
|
Paths_Purr
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
src
|
src
|
||||||
|
default-extensions:
|
||||||
|
OverloadedStrings
|
||||||
|
GeneralizedNewtypeDeriving
|
||||||
|
DeriveGeneric
|
||||||
|
ConstraintKinds
|
||||||
|
FlexibleContexts
|
||||||
|
FlexibleInstances
|
||||||
|
ScopedTypeVariables
|
||||||
build-depends:
|
build-depends:
|
||||||
base >=4.7 && <5
|
AesonBson ==0.4.1
|
||||||
|
, aeson >=2.0.0.0
|
||||||
|
, base >=4.7
|
||||||
|
, bson >=0.3
|
||||||
|
, dhall >=1.40 && <1.41.2
|
||||||
|
, http-types >=0.12.3
|
||||||
|
, iso8601-time >=0.1.5
|
||||||
|
, mongoDB >=2.7.1.1
|
||||||
|
, mtl >=2.2.2
|
||||||
|
, scotty ==0.12
|
||||||
|
, text >=1.2
|
||||||
|
, time >=1.9
|
||||||
|
, wai-extra >=3.1.12.1
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
executable Purr-exe
|
executable Purr-exe
|
||||||
@ -34,10 +59,30 @@ executable Purr-exe
|
|||||||
Paths_Purr
|
Paths_Purr
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
app
|
app
|
||||||
|
default-extensions:
|
||||||
|
OverloadedStrings
|
||||||
|
GeneralizedNewtypeDeriving
|
||||||
|
DeriveGeneric
|
||||||
|
ConstraintKinds
|
||||||
|
FlexibleContexts
|
||||||
|
FlexibleInstances
|
||||||
|
ScopedTypeVariables
|
||||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||||
build-depends:
|
build-depends:
|
||||||
Purr
|
AesonBson ==0.4.1
|
||||||
, base >=4.7 && <5
|
, Purr
|
||||||
|
, aeson >=2.0.0.0
|
||||||
|
, base >=4.7
|
||||||
|
, bson >=0.3
|
||||||
|
, dhall >=1.40 && <1.41.2
|
||||||
|
, http-types >=0.12.3
|
||||||
|
, iso8601-time >=0.1.5
|
||||||
|
, mongoDB >=2.7.1.1
|
||||||
|
, mtl >=2.2.2
|
||||||
|
, scotty ==0.12
|
||||||
|
, text >=1.2
|
||||||
|
, time >=1.9
|
||||||
|
, wai-extra >=3.1.12.1
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
test-suite Purr-test
|
test-suite Purr-test
|
||||||
@ -47,8 +92,28 @@ test-suite Purr-test
|
|||||||
Paths_Purr
|
Paths_Purr
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
test
|
test
|
||||||
|
default-extensions:
|
||||||
|
OverloadedStrings
|
||||||
|
GeneralizedNewtypeDeriving
|
||||||
|
DeriveGeneric
|
||||||
|
ConstraintKinds
|
||||||
|
FlexibleContexts
|
||||||
|
FlexibleInstances
|
||||||
|
ScopedTypeVariables
|
||||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||||
build-depends:
|
build-depends:
|
||||||
Purr
|
AesonBson ==0.4.1
|
||||||
, base >=4.7 && <5
|
, Purr
|
||||||
|
, aeson >=2.0.0.0
|
||||||
|
, base >=4.7
|
||||||
|
, bson >=0.3
|
||||||
|
, dhall >=1.40 && <1.41.2
|
||||||
|
, http-types >=0.12.3
|
||||||
|
, iso8601-time >=0.1.5
|
||||||
|
, mongoDB >=2.7.1.1
|
||||||
|
, mtl >=2.2.2
|
||||||
|
, scotty ==0.12
|
||||||
|
, text >=1.2
|
||||||
|
, time >=1.9
|
||||||
|
, wai-extra >=3.1.12.1
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
import Lib
|
import Prelude
|
||||||
|
import qualified Lib
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = someFunc
|
main = Lib.main
|
||||||
|
11
examples/Dockerfile
Normal file
11
examples/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
FROM haskell:9.0.2
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
ADD . /app
|
||||||
|
|
||||||
|
RUN stack setup
|
||||||
|
RUN stack build --copy-bins --local-bin-path ./
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD ./Purr-exe
|
10
examples/config.dhall
Normal file
10
examples/config.dhall
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
-- /config.dhall
|
||||||
|
{ hostname = "localhost"
|
||||||
|
, port = +3001
|
||||||
|
, environment = "development"
|
||||||
|
, adminDB = "admin"
|
||||||
|
, dataDB = "data"
|
||||||
|
, collection = "store"
|
||||||
|
, mongoUsername = "root"
|
||||||
|
, mongoPassword = "REPLACEME"
|
||||||
|
}
|
23
package.yaml
23
package.yaml
@ -9,6 +9,15 @@ extra-source-files:
|
|||||||
- README.md
|
- README.md
|
||||||
- ChangeLog.md
|
- ChangeLog.md
|
||||||
|
|
||||||
|
default-extensions:
|
||||||
|
- OverloadedStrings
|
||||||
|
- GeneralizedNewtypeDeriving
|
||||||
|
- DeriveGeneric
|
||||||
|
- ConstraintKinds
|
||||||
|
- FlexibleContexts
|
||||||
|
- FlexibleInstances
|
||||||
|
- ScopedTypeVariables
|
||||||
|
|
||||||
# Metadata used when publishing your package
|
# Metadata used when publishing your package
|
||||||
# synopsis: Short description of your package
|
# synopsis: Short description of your package
|
||||||
# category: Web
|
# category: Web
|
||||||
@ -19,7 +28,19 @@ extra-source-files:
|
|||||||
description: https://git.eversole.co/James/Purr
|
description: https://git.eversole.co/James/Purr
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- base >= 4.7 && < 5
|
- aeson >= 2.0.0.0
|
||||||
|
- AesonBson == 0.4.1
|
||||||
|
- bson >= 0.3
|
||||||
|
- base >= 4.7
|
||||||
|
- dhall >= 1.40 && < 1.41.2
|
||||||
|
- http-types >= 0.12.3
|
||||||
|
- iso8601-time >= 0.1.5
|
||||||
|
- mongoDB >= 2.7.1.1
|
||||||
|
- mtl >= 2.2.2
|
||||||
|
- scotty == 0.12
|
||||||
|
- time >= 1.9
|
||||||
|
- text >= 1.2
|
||||||
|
- wai-extra >= 3.1.12.1
|
||||||
|
|
||||||
library:
|
library:
|
||||||
source-dirs: src
|
source-dirs: src
|
||||||
|
11
src/Core/Configuration.hs
Normal file
11
src/Core/Configuration.hs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module Core.Configuration ( main ) where
|
||||||
|
|
||||||
|
import Core.Types
|
||||||
|
|
||||||
|
import Dhall
|
||||||
|
|
||||||
|
instance FromDhall DhallConfig
|
||||||
|
|
||||||
|
main :: IO DhallConfig
|
||||||
|
main = do
|
||||||
|
input auto "./config.dhall"
|
14
src/Core/HTTP.hs
Normal file
14
src/Core/HTTP.hs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module Core.HTTP ( app ) where
|
||||||
|
|
||||||
|
import Core.Types
|
||||||
|
|
||||||
|
import Feature.Handlers as RES
|
||||||
|
|
||||||
|
import Network.Wai.Middleware.RequestLogger (logStdoutDev)
|
||||||
|
import Web.Scotty.Trans
|
||||||
|
|
||||||
|
app :: PurrApp ()
|
||||||
|
app = do
|
||||||
|
middleware logStdoutDev
|
||||||
|
|
||||||
|
get "/" RES.root
|
20
src/Core/Mongo.hs
Normal file
20
src/Core/Mongo.hs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
module Core.Mongo ( mongoSetup, tempGetDocs ) where
|
||||||
|
|
||||||
|
import Core.Types
|
||||||
|
|
||||||
|
import Control.Monad.Reader (MonadIO)
|
||||||
|
import Database.MongoDB
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
mongoSetup :: DhallConfig -> IO MongoContext
|
||||||
|
mongoSetup conf = do
|
||||||
|
mongoCon <- connect $ host (hostname conf)
|
||||||
|
let adminCon = MongoContext mongoCon master (adminDB conf)
|
||||||
|
access (mongoPipe adminCon) (mongoAccessMode adminCon) (mongoDatabase adminCon) (auth (mongoUsername conf) (mongoPassword conf))
|
||||||
|
return $ MongoContext mongoCon master (dataDB conf)
|
||||||
|
|
||||||
|
tempGetDocs :: MonadIO m => AppConfig -> m [Document]
|
||||||
|
tempGetDocs appConfig = access (mongoPipe db) (mongoAccessMode db) (mongoDatabase db) $ find (select [] (collection conf)) >>= rest
|
||||||
|
where
|
||||||
|
db = dbconn appConfig
|
||||||
|
conf = res appConfig
|
34
src/Core/Types.hs
Normal file
34
src/Core/Types.hs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
module Core.Types where
|
||||||
|
|
||||||
|
import qualified Data.Text.Lazy as LT
|
||||||
|
|
||||||
|
import Control.Monad.Reader (MonadIO, MonadReader, ReaderT)
|
||||||
|
import Data.Text
|
||||||
|
import Database.MongoDB (MongoContext)
|
||||||
|
import GHC.Generics (Generic)
|
||||||
|
import Numeric.Natural (Natural)
|
||||||
|
import Web.Scotty.Trans (ScottyT, ActionT)
|
||||||
|
|
||||||
|
type PurrApp a = ScottyT LT.Text ConfigM a
|
||||||
|
type PurrAction a = ActionT LT.Text ConfigM a
|
||||||
|
|
||||||
|
newtype ConfigM a = ConfigM
|
||||||
|
{ runConfigM :: ReaderT AppConfig IO a
|
||||||
|
} deriving (Applicative, Functor, Monad, MonadIO, MonadReader AppConfig)
|
||||||
|
|
||||||
|
data AppConfig = AppConfig
|
||||||
|
{ res :: DhallConfig
|
||||||
|
, dbconn :: MongoContext
|
||||||
|
}
|
||||||
|
|
||||||
|
data DhallConfig = DhallConfig
|
||||||
|
{ hostname :: String
|
||||||
|
, port :: Int
|
||||||
|
, environment :: Text
|
||||||
|
, adminDB :: Text
|
||||||
|
, dataDB :: Text
|
||||||
|
, collection :: Text
|
||||||
|
, mongoUsername :: Text
|
||||||
|
, mongoPassword :: Text
|
||||||
|
} deriving (Generic, Show)
|
||||||
|
|
18
src/Feature/Handlers.hs
Normal file
18
src/Feature/Handlers.hs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module Feature.Handlers ( root ) where
|
||||||
|
|
||||||
|
import Core.Types
|
||||||
|
import qualified Core.Mongo as DB
|
||||||
|
|
||||||
|
import Control.Monad.Reader (ask, lift)
|
||||||
|
import Data.AesonBson (aesonify)
|
||||||
|
import Data.Bson (Document, Field (..), Value (Array, Doc))
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.Lazy as LT
|
||||||
|
import Web.Scotty.Trans (json)
|
||||||
|
import Prelude hiding (id)
|
||||||
|
|
||||||
|
root :: PurrAction ()
|
||||||
|
root = do
|
||||||
|
config <- lift $ ask
|
||||||
|
docs <- DB.tempGetDocs config
|
||||||
|
json $ aesonify ["allDocs" := Array (map Doc docs)]
|
27
src/Lib.hs
27
src/Lib.hs
@ -1,6 +1,23 @@
|
|||||||
module Lib
|
module Lib ( main ) where
|
||||||
( someFunc
|
|
||||||
) where
|
|
||||||
|
|
||||||
someFunc :: IO ()
|
import Core.Types
|
||||||
someFunc = putStrLn "someFunc"
|
import qualified Core.Configuration as Configuration
|
||||||
|
import qualified Core.HTTP as HTTP
|
||||||
|
import qualified Core.Mongo as DB
|
||||||
|
|
||||||
|
import Control.Monad.Reader (liftIO, runReaderT)
|
||||||
|
import Database.MongoDB (MongoContext)
|
||||||
|
import GHC.Natural (popCountNatural)
|
||||||
|
import Web.Scotty.Trans (scottyT)
|
||||||
|
import Prelude hiding (id)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
dhallConf <- liftIO Configuration.main
|
||||||
|
dataDB <- liftIO $ DB.mongoSetup dhallConf
|
||||||
|
let config = AppConfig { res = dhallConf
|
||||||
|
, dbconn = dataDB
|
||||||
|
}
|
||||||
|
scottyT (port dhallConf) (flip runApp config) HTTP.app where
|
||||||
|
runApp :: ConfigM a -> AppConfig -> IO a
|
||||||
|
runApp m c = runReaderT (runConfigM m) c
|
||||||
|
@ -35,12 +35,9 @@ packages:
|
|||||||
# These entries can reference officially published versions as well as
|
# These entries can reference officially published versions as well as
|
||||||
# forks / in-progress versions pinned to a git hash. For example:
|
# forks / in-progress versions pinned to a git hash. For example:
|
||||||
#
|
#
|
||||||
# extra-deps:
|
extra-deps:
|
||||||
# - acme-missiles-0.3
|
- AesonBson-0.4.1@sha256:30a4ecb39e8da94dc1e1e8945eb0d4e33a833ae4342841b3c87c56b5918a90a1,1398
|
||||||
# - git: https://github.com/commercialhaskell/stack.git
|
- bson-generic-0.0.9@sha256:ea6685daa618b2bbe6e189c33e195e812501baf42f53183eedc16f011690895a,817
|
||||||
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
|
||||||
#
|
|
||||||
# extra-deps: []
|
|
||||||
|
|
||||||
# Override default flag values for local packages and extra-deps
|
# Override default flag values for local packages and extra-deps
|
||||||
# flags: {}
|
# flags: {}
|
||||||
|
@ -3,7 +3,21 @@
|
|||||||
# For more information, please see the documentation at:
|
# For more information, please see the documentation at:
|
||||||
# https://docs.haskellstack.org/en/stable/lock_files
|
# https://docs.haskellstack.org/en/stable/lock_files
|
||||||
|
|
||||||
packages: []
|
packages:
|
||||||
|
- completed:
|
||||||
|
hackage: AesonBson-0.4.1@sha256:30a4ecb39e8da94dc1e1e8945eb0d4e33a833ae4342841b3c87c56b5918a90a1,1398
|
||||||
|
pantry-tree:
|
||||||
|
size: 378
|
||||||
|
sha256: 10c7444de357f7fc1473542d8b3307811420889be32d5a2033d0dbc2d32a375d
|
||||||
|
original:
|
||||||
|
hackage: AesonBson-0.4.1@sha256:30a4ecb39e8da94dc1e1e8945eb0d4e33a833ae4342841b3c87c56b5918a90a1,1398
|
||||||
|
- completed:
|
||||||
|
hackage: bson-generic-0.0.9@sha256:ea6685daa618b2bbe6e189c33e195e812501baf42f53183eedc16f011690895a,817
|
||||||
|
pantry-tree:
|
||||||
|
size: 220
|
||||||
|
sha256: 46d452c35c2c762af25bf4d85b5248a94cbbe5b282bc4b1217d0ab3451011ae9
|
||||||
|
original:
|
||||||
|
hackage: bson-generic-0.0.9@sha256:ea6685daa618b2bbe6e189c33e195e812501baf42f53183eedc16f011690895a,817
|
||||||
snapshots:
|
snapshots:
|
||||||
- completed:
|
- completed:
|
||||||
size: 618740
|
size: 618740
|
||||||
|
Loading…
x
Reference in New Issue
Block a user