Open eviefp opened 4 years ago
I've been vaguely thinking about introducing something like Servant's natural transformation API to allow use cases like this. This should be possible.
In our project, we handle this outside of the payload library, by mapping over the handlers record and running our own monad.
handlers env =
runHandlers env
{ avatarDelete: avatarDelete :: _ -> ServerM _
, avatarSignedUrl: avatarSignedUrl :: _ -> ServerM _
, changeEmail: changeEmail :: _ -> ServerM _
, hasuraAuthenticate: hasuraAuthenticate :: _ -> ServerM _
, hasuraAuthenticateAdmin: hasuraAuthenticateAdmin :: _ -> ServerM _
, hasuraAuthenticateNotVerified: hasuraAuthenticateNotVerified :: _ -> ServerM _
, signIn: signIn :: _ -> ServerM _
, signInGoogle: signInGoogle :: _ -> ServerM _
, signInLinkedin: signInLinkedin :: _ -> ServerM _
, register: register :: _ -> ServerM _
, checkUser: checkUser :: _ -> ServerM _
, renderPdf: renderPdf :: _ -> ServerM _
, resetPassword: resetPassword :: _ -> ServerM _
, sendPasswordResetEmail: sendPasswordResetEmail :: _ -> ServerM _
, sendVerificationEmail: sendVerificationEmail :: _ -> ServerM _
, verifyEmail: verifyEmail :: _ -> ServerM _
, hasuraPublic: hasuraPublic :: _ -> ServerM _
}
...
import Prelude
import Data.Maybe (Maybe(..))
import Data.Symbol (class IsSymbol, SProxy, reflectSymbol)
import Effect.Aff (Aff)
import Env (Env(..))
import Heterogeneous.Mapping (class HMapWithIndex, class MappingWithIndex, hmapWithIndex)
import ServerM (ServerM, runServerM)
data RunHandler
= RunHandler Env
instance runHandler ::
( IsSymbol sym
) =>
MappingWithIndex RunHandler (SProxy sym) (r -> ServerM res) (r -> Aff res) where
mappingWithIndex (RunHandler (Env env)) sym h req =
runServerM
( Env
env
{ path = Just $ reflectSymbol sym }
)
(h req)
runHandlers ::
forall serverMs affs.
HMapWithIndex RunHandler serverMs affs => Env -> serverMs -> affs
runHandlers = hmapWithIndex <<< RunHandler
While looking into payload, I was trying to write some simple example of an API and rather than use a real DB, I figured I'd use a
StateT
transformer to keep some state across API calls, but I noticed the exposed functions force handlers to run inAff
.I assume it should be possible to relax the requirement to
MonadAff
?