-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A REST Web Api server template for building (micro)services. -- -- A REST Web Api server template, that serves as a reference and avoids -- repetive boilerplate when building many (micro)services. This combines -- best libraries available in Haskell web development, like RIO, warp, -- servant, etc., and principles around 12-factor app. -- -- Check Chakra module documentation for example. -- -- Idea is to provide Curated & Opinionated set of packages and -- patterns to build well designed web api applications in Haskell. -- -- Inspiration from Python Flask, ASP.NET Core -- -- For more details, please see the README on Github at -- https://github.com/cackharot/haskell-web-api-template#readme @package chakra @version 0.1.0 -- | Config utility module, uses System.Envy to read ENV values and builds -- a data module Chakra.Config -- | Read from ENVIRONMENT Variables and return your target t data -- t should have a instance of FromEnv Example: instance -- FromEnv MyAppSettings withAppSettingsFromEnv :: FromEnv t => (t -> IO ()) -> IO () -- | Contains JWT authentication settings module Chakra.JWT -- | Build JWT settings to be used in Servant Auth context Looks for -- JWK_AUDIENCES and JWK_PATH in environment values to -- load the sig file and value to verify the incoming jwt audience claim getJWTAuthSettings :: IO JWTSettings buildJWTSettings :: JWK -> JWKSet -> (StringOrURI -> IsMatch) -> JWTSettings acquireJwks :: IO JWKSet -- | Logging utility functions module Chakra.Logging data LogMessage type ModLogger = LogFunc type Formatter = TimedFastLogger -> CallStack -> LogSource -> LogLevel -> Utf8Builder -> IO () -- | Builds LogMessage and json encodes to string jsonFormatter :: Text -> Text -> Formatter -- | Creates a logger module using a given formatting function. | Also -- returns the underlying TimedFastLogger for use outside of your app -- (e.g. in some WAI middleware). newLogger :: LogType -> Formatter -> IO (TimedFastLogger, ModLogger) -- | Convenient function to create json formatted logger with appName & -- appVer values buildLogger :: Text -> Text -> IO ModLogger instance GHC.Generics.Generic Chakra.Logging.LogMessage instance GHC.Show.Show Chakra.Logging.LogMessage instance GHC.Classes.Eq Chakra.Logging.LogMessage instance Data.Aeson.Types.ToJSON.ToJSON Chakra.Logging.LogMessage instance System.Log.FastLogger.LogStr.ToLogStr Chakra.Logging.LogMessage instance Data.Has.Has Chakra.Logging.ModLogger a => RIO.Prelude.Logger.HasLogFunc a -- | Types module Chakra.Types data InfoDetail InfoDetail :: !Text -> !Text -> !Text -> !Text -> InfoDetail [appName] :: InfoDetail -> !Text [appEnvironment] :: InfoDetail -> !Text [appVersion] :: InfoDetail -> !Text [appDescription] :: InfoDetail -> !Text data AuthenticatedUser AuthenticatedUser :: !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> AuthenticatedUser [aud] :: AuthenticatedUser -> !Text [iss] :: AuthenticatedUser -> !Text [appid] :: AuthenticatedUser -> !Text [aio] :: AuthenticatedUser -> !Text [oid] :: AuthenticatedUser -> !Text [sub] :: AuthenticatedUser -> !Text [tid] :: AuthenticatedUser -> !Text instance GHC.Generics.Generic Chakra.Types.InfoDetail instance GHC.Classes.Eq Chakra.Types.InfoDetail instance GHC.Show.Show Chakra.Types.InfoDetail instance GHC.Generics.Generic Chakra.Types.AuthenticatedUser instance GHC.Show.Show Chakra.Types.AuthenticatedUser instance Data.Aeson.Types.ToJSON.ToJSON Chakra.Types.AuthenticatedUser instance Data.Aeson.Types.FromJSON.FromJSON Chakra.Types.AuthenticatedUser instance Servant.Auth.JWT.ToJWT Chakra.Types.AuthenticatedUser instance Servant.Auth.JWT.FromJWT Chakra.Types.AuthenticatedUser instance System.Envy.FromEnv Chakra.Types.InfoDetail instance Data.Default.Class.Default Chakra.Types.InfoDetail instance Data.Aeson.Types.ToJSON.ToJSON Chakra.Types.InfoDetail -- | As name suggests few utilities to make life easier module Chakra.Util -- | Construct plain ServerError Type with given status code and error text errText :: ServerError -> ByteString -> ServerError -- | Creates and throws a simple text/plain ServerError. throwErrText :: MonadThrow u => ServerError -> ByteString -> u a -- | Throws Unauthorized error throwUnauthorized :: MonadThrow u => u a -- | Custom JSON payload error formatter jsonErrorFormatter :: ErrorFormatter -- | Custom JSON payload error formatter for 404 notFoundFormatter :: NotFoundErrorFormatter -- | Gets a value of any type from the context. askObj :: (Has β α, MonadReader α μ) => μ β -- | Gets a thing from a value of any type from the context. (Useful for -- configuration fields.) askOpt :: (Has β α, MonadReader α μ) => (β -> ψ) -> μ ψ module Network.Wai.Middleware.Health health :: Middleware module Network.Wai.Middleware.Info info :: ByteString -> Middleware -- | Defines convenience functions to run a servant base api in wrap server module Chakra.App -- | Setup servant with custom context so that the handers can take custom -- effects/ctx chakraApp :: forall β χ ψ. (HasServer χ ψ, HasContextEntry (ψ .++ DefaultErrorFormatters) ErrorFormatters) => Context ψ -> β -> Proxy χ -> ServerT χ (RIO β) -> Application -- | Starts the warp server with given middlewares, context, api definition -- and api server Does not enable/registers GHC internal metrics runChakraApp :: (MonadIO m, HasServer χ ψ, HasContextEntry (ψ .++ DefaultErrorFormatters) ErrorFormatters) => Middleware -> Context ψ -> β -> Proxy χ -> ServerT χ (RIO β) -> m () -- | Starts the warp server with given middlewares, context, api definition -- and api server Enables prometheus metrics (with GHC internal metrics) -- (Needs -with-rtsopts=-T) runChakraAppWithMetrics :: (MonadIO m, HasServer χ ψ, HasContextEntry (ψ .++ DefaultErrorFormatters) ErrorFormatters) => Middleware -> Context ψ -> β -> Proxy χ -> ServerT χ (RIO β) -> m () -- | Return default set of middlewares applied chakraMiddlewares :: InfoDetail -> IO Middleware -- | Registers GHC runtime metrics so that /metrics endpoint will return -- rich GHC info Requires `-with-rtsopts=-T` registerMetrics :: MonadIO m => m GHCMetrics -- | Custom Servant Error formatter overrides to return in JSON format chakraErrorFormatters :: ErrorFormatters -- | Natural transformation to run handlers in RIO monad instead of -- ServantT runChakraHandler :: a -> RIO a h -> Handler h -- | This module re-exports all functionality of this package for easy use. -- Users expected to import this module only. -- -- Examples: -- --
-- import Chakra ---- --
-- #!/usr/bin/env stack
-- {- stack --resolver lts-14.27 runghc --package chakra -}
-- {-# LANGUAGE NoImplicitPrelude, OverloadedStrings, UnicodeSyntax, DataKinds, TypeOperators #-}
-- import RIO
-- import Chakra
-- import Servant
--
-- type HelloRoute = "hello" :> QueryParam "name" Text :> Get '[PlainText] Text
-- type API = HelloRoute :| EmptyAPI
--
-- hello :: Maybe Text -> BasicApp Text
-- hello name = do
-- let name' = fromMaybe "Sensei!" name
-- logInfo $ "Saying hello to " <> display name'
-- return $ "Hello " <> name' <> "!"
--
-- main :: IO ()
-- main = do
-- let infoDetail = InfoDetail "example" "dev" "0.1" "change me"
-- appEnv = appEnvironment infoDetail
-- appVer = appVersion infoDetail
-- appAPI = Proxy :: Proxy API
-- appServer = hello :| emptyServer
-- logFunc <- buildLogger appEnv appVer
-- middlewares <- chakraMiddlewares infoDetail
-- runChakraAppWithMetrics
-- middlewares
-- EmptyContext
-- (logFunc, infoDetail)
-- appAPI
-- appServer
--
module Chakra
-- | Nice type synonym to mark your servant handlers For real life you need
-- to create one for your application
type BasicApp = RIO BasicAppCtx
-- | Basic application context, mostly used in examples. For real life you
-- need to create one for your application
type BasicAppCtx = (ModLogger, InfoDetail)