Hello,
I found working example on how to work with forms in hyper and examples in hypertrout for routing, but not sure how to combine them, I have separated function that defines resources and function that create router, but return type of resources is disalloving me from calling parseForm
.
module Main where
import Prelude
import Control.Monad.Indexed.Qualified as Ix
import Control.Monad.Except (ExceptT)
import Control.Monad.Reader (ReaderT, ask, runReaderT)
import Data.Maybe (fromMaybe, Maybe)
import Effect (Effect)
import Effect.Aff (Aff)
import Hyper.Conn (Conn)
import Hyper.Status (Status)
import Hyper.Middleware (Middleware)
import Hyper.Node.Server (defaultOptionsWithLogging, runServer', HttpRequest, HttpResponse)
import Hyper.Response (closeHeaders, respond, writeStatus, StatusLineOpen, ResponseEnded)
import Hyper.Trout.Router (RoutingError, router)
import Text.Smolder.HTML.Attributes (method, for, id, name)
import Text.Smolder.HTML (p, form, label, input, button)
import Text.Smolder.Markup (text, (!))
import Type.Proxy (Proxy(..))
import Type.Trout (type (:=), type(:<|>), Resource)
import Type.Trout.ContentType.HTML (class EncodeHTML, HTML)
import Type.Trout.Method (Get, Post)
type ComponentsType = Record ()
type ConnHttp resp = Conn HttpRequest (HttpResponse resp) ComponentsType
type Env = String
type AppM m = ReaderT Env m
data GreetForm = GreetForm
data GreetPost = GreetPost String
type Site = "greeting" := Resource (Get GreetForm HTML :<|> Post GreetPost HTML)
instance encodeHTMLGreetForm :: EncodeHTML GreetForm where
encodeHTML GreetForm =
form ! method "post" $ do
label ! for "name" $ text "Name"
input ! id "name" ! name "name"
button $ text "Greet"
instance encodeHTMLGreetPost :: EncodeHTML GreetPost where
encodeHTML (GreetPost g) = p (text g)
runAppM ∷ forall a. String -> (AppM Aff a) -> Aff a
runAppM = flip runReaderT
site :: Proxy Site
site = Proxy
resources :: forall m. Monad m =>
{ "greeting" ::
{ "GET" :: ExceptT RoutingError (AppM m) GreetForm
, "POST" :: ExceptT RoutingError (AppM m) GreetPost
}
}
resources =
{ "greeting":
{ "GET": pure GreetForm
, "POST": (GreetPost <$> ask) -- here call somehow parseForm??
}
}
onRoutingError :: Status -> Maybe String -> Middleware (AppM Aff) (ConnHttp StatusLineOpen) (ConnHttp ResponseEnded) Unit
onRoutingError status msg = Ix.do
writeStatus status
closeHeaders
respond (fromMaybe "" msg)
handler :: Middleware (AppM Aff) (ConnHttp StatusLineOpen) (ConnHttp ResponseEnded) Unit
handler = router site resources onRoutingError -- I would not call parseForm here because it would be called on every request??
main :: Effect Unit
main = runServer' defaultOptionsWithLogging {} (runAppM "Ahoj") handler
EDIT:
Found out that actualy I’m supposed to use hyperroute for this, but could anybody provide any example of how to use it? Mainly what to pass to ReqBody second argument ctx
FINALL:
It is probably not supported, so maybe I will migrate to nodetrout as recommended