1111
1212module Orb.Handler.Handler
1313 ( Handler (.. )
14- , HandlerRequest (.. )
14+ , RequestWithBody (.. )
15+ , HandlerRequest
16+ , PermissionRequest
1517 , runHandler
1618 , HasHandler (.. )
1719 , NoRequestBody (.. )
@@ -23,6 +25,8 @@ module Orb.Handler.Handler
2325 , formDataRequestBody
2426 , formDataRequestBodyWith
2527 , emptyRequestBody
28+ , BodyHandle
29+ , decodeBody
2630 , NoRequestQuery (.. )
2731 , RequestQuery (.. )
2832 , schemaRequestQuery
@@ -38,6 +42,7 @@ module Orb.Handler.Handler
3842where
3943
4044import Beeline.Params qualified as BP
45+ import Control.Concurrent.MVar qualified as MVar
4146import Control.Exception.Safe qualified as Safe
4247import Control.Monad.IO.Class qualified as MIO
4348import Data.ByteString.Lazy qualified as LBS
@@ -58,21 +63,29 @@ import Orb.HasRequest qualified as HasRequest
5863import Orb.HasRespond qualified as HasRespond
5964import Orb.Response qualified as Response
6065
61- data HandlerRequest route = HandlerRequest
66+ data RequestWithBody body route = HandlerRequest
6267 { reqRoute :: route
63- , reqBody :: HandlerRequestBody route
68+ , reqBody :: body
6469 , reqQuery :: HandlerRequestQuery route
6570 , reqHeaders :: HandlerRequestHeaders route
6671 }
6772
73+ type HandlerRequest route =
74+ RequestWithBody (HandlerRequestBody route ) route
75+
76+ type PermissionRequest route =
77+ RequestWithBody
78+ (BodyHandle (S. TaggedUnion (HandlerResponses route )) (HandlerRequestBody route ))
79+ route
80+
6881data Handler route = Handler
6982 { handlerId :: String
7083 , requestBody :: RequestBody (HandlerRequestBody route ) (HandlerResponses route )
7184 , handlerResponseBodies :: Response. ResponseBodies (HandlerResponses route )
7285 , requestQuery :: RequestQuery (HandlerRequestQuery route ) (HandlerResponses route )
7386 , requestHeaders :: RequestHeaders (HandlerRequestHeaders route ) (HandlerResponses route )
7487 , mkPermissionAction ::
75- HandlerRequest route ->
88+ PermissionRequest route ->
7689 HandlerPermissionAction route
7790 , handleRequest ::
7891 HandlerRequest route ->
@@ -180,6 +193,27 @@ emptyRequestBody =
180193 , requestBodyParser = const (pure (Right NoRequestBody ))
181194 }
182195
196+ newtype BodyHandle err body
197+ = BodyHandle (IO (Either err body ))
198+
199+ decodeBody :: MIO. MonadIO m => BodyHandle err body -> m (Either err body )
200+ decodeBody (BodyHandle decode) =
201+ MIO. liftIO decode
202+
203+ newBodyHandle :: IO (Either err body ) -> IO (BodyHandle err body )
204+ newBodyHandle decode = do
205+ cacheVar <- MVar. newMVar Nothing
206+ pure . BodyHandle $ do
207+ exceptionOrResult <-
208+ MVar. modifyMVar cacheVar $ \ cached ->
209+ case cached of
210+ Just result ->
211+ pure (cached, result)
212+ Nothing -> do
213+ result <- Safe. tryAny decode
214+ pure (Just result, result)
215+ either Safe. throwIO pure exceptionOrResult
216+
183217data NoRequestQuery
184218 = NoRequestQuery
185219
@@ -278,20 +312,14 @@ runHandler handler route = do
278312 Left errResponse ->
279313 pure errResponse
280314 Right query -> do
281- errOrBody <- readBody handler
282- case errOrBody of
283- Left errResponse -> pure errResponse
284- Right body ->
285- let
286- request =
287- HandlerRequest
288- { reqRoute = route
289- , reqBody = body
290- , reqQuery = query
291- , reqHeaders = headers
292- }
293- in
294- runPermissionAction handler request
315+ body <- newRequestBodyHandle handler
316+ runPermissionAction handler $
317+ HandlerRequest
318+ { reqRoute = route
319+ , reqBody = body
320+ , reqQuery = query
321+ , reqHeaders = headers
322+ }
295323
296324 let
297325 responseData =
@@ -330,39 +358,44 @@ readQuery ::
330358readQuery handler =
331359 requestQueryParser (requestQuery handler) <$> HasRequest. request
332360
333- readBody ::
361+ newRequestBodyHandle ::
334362 ( MIO. MonadIO m
335363 , HasRequest. HasRequest m
336364 , tags ~ HandlerResponses route
337365 ) =>
338366 Handler route ->
339- m (Either (S. TaggedUnion tags ) (HandlerRequestBody route ))
340- readBody handler = do
367+ m (BodyHandle (S. TaggedUnion tags ) (HandlerRequestBody route ))
368+ newRequestBodyHandle handler = do
341369 req <- HasRequest. request
342- MIO. liftIO $ requestBodyParser (requestBody handler) req
370+ MIO. liftIO . newBodyHandle $ requestBodyParser (requestBody handler) req
343371
344372runPermissionAction ::
345- ( Monad m
373+ ( MIO. MonadIO m
346374 , HasHandler route
347375 , PA. PermissionActionMonad (HandlerPermissionAction route ) ~ m
348376 ) =>
349377 Handler route ->
350- HandlerRequest route ->
378+ PermissionRequest route ->
351379 m (S. TaggedUnion (HandlerResponses route ))
352- runPermissionAction handler request = do
380+ runPermissionAction handler permissionRequest = do
353381 let
354382 permissionAction =
355- mkPermissionAction handler request
383+ mkPermissionAction handler permissionRequest
356384
357385 errOrPermissionResult <- PA. checkPermissionAction permissionAction
358386
359387 case errOrPermissionResult of
360388 Left err -> PE. returnPermissionError err
361- Right permissionResult ->
362- PA. runPermissionActionHandler
363- permissionAction
364- permissionResult
365- (handleRequest handler request)
389+ Right permissionResult -> do
390+ errOrBody <- decodeBody (reqBody permissionRequest)
391+ case errOrBody of
392+ Left errResponse ->
393+ pure errResponse
394+ Right body ->
395+ PA. runPermissionActionHandler
396+ permissionAction
397+ permissionResult
398+ (handleRequest handler permissionRequest {reqBody = body})
366399
367400returnAnyExceptionAs500 ::
368401 ( MIO. MonadIO m
0 commit comments