wai-transformers

[ bsd3, library, unclassified ] [ Propose Tags ]

Modules

[Index]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.0.1, 0.0.2, 0.0.3, 0.0.4, 0.0.5, 0.0.5.1, 0.0.6, 0.0.7, 0.1.0 (info)
Dependencies base (>=4.8 && <5), exceptions, extractable-singleton (>=0.0.1), monad-control-aligned (>=0.0.1), transformers, wai (>=3.2.1), wai-websockets, websockets (>=0.12.4) [details]
License BSD-3-Clause
Copyright 2018 Athan Clark
Author Athan Clark
Maintainer athan.clark@localcooking.com
Home page https://github.com/athanclark/wai-transformers#readme
Bug tracker https://github.com/athanclark/wai-transformers/issues
Source repo head: git clone https://github.com/athanclark/wai-transformers
Uploaded by athanclark at 2018-03-22T14:10:30Z
Distributions LTSHaskell:0.1.0, Stackage:0.1.0
Reverse Dependencies 8 direct, 2 indirect [details]
Downloads 5591 total (33 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2018-03-22 [all 1 reports]

Readme for wai-transformers-0.1.0

[back to package description]

wai-transformers

Simple parameterization of Wai's Application and Middleware types.

Overview

Wai's Application type is defined as follows:

type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived

This is great for the server - we can just flip ($) the middlewares together to get an effectful server. However, what if we want to encode useful information in our middleware chain / end-point application? Something like a ReaderT Env environment, where useful data like a universal salt, current hostname, or global mutable references can be referenced later if it were wedged-in.

The design looks like this:

type ApplicationT m = Request -> (Response -> IO ResponseReceived) -> m ResponseReceived

Now we can encode MTL-style contexts with applications we write

type MiddlewareT m = ApplicationT m -> ApplicationT m


data AuthConfig = AuthConfig
  { authFunction :: Request -> Either AuthException (Response -> Response)
  }

simpleAuth :: ( MonadReader AuthConfig m
              , MonadError AuthException m
              ) => MiddlewareT m
simpleAuth app req resp = do
  auth <- authFunction <$> ask
  case auth req of
    Left e = throwError e
    Right f = app req (resp . f)

simpleAuth' :: Middleware
simpleAuth' app req resp =
  eReceived <- runExceptT $ runReaderT (simpleAuth app req resp) myAuthConfig
  case eReceived of
    Left e = resp $ respondLBS "Unauthorized!"
    Right r = return r