Remove Handler type in favor of a type variable for ServerRequest type.

This commit is contained in:
Dillon Kearns 2021-12-31 11:14:23 -08:00
parent 04ebcc0190
commit 3aae8c1adf
10 changed files with 103 additions and 126 deletions

View File

@ -5,6 +5,7 @@ import DataSource exposing (DataSource)
import DataSource.Http
import DataSource.ServerRequest as ServerRequest exposing (ServerRequest)
import Html exposing (Html)
import Json.Decode
import Json.Encode
import OptimizedDecoder as Decode
import QueryParams
@ -28,9 +29,31 @@ routes getStaticRoutes htmlToString =
, logout
, greet
, fileLength
, jsonError
]
jsonError : Server.Request.ServerRequest ServerResponse.ServerResponse
jsonError =
Server.Request.oneOf
[ Server.Request.jsonBodyResult (Decode.field "name" Decode.string)
|> Server.Request.map
(\result ->
case result of
Ok firstName ->
ServerResponse.stringBody
("Hello " ++ firstName)
Err decodeError ->
decodeError
|> Json.Decode.errorToString
|> ServerResponse.stringBody
|> ServerResponse.withStatusCode 400
)
, Server.Request.succeed (ServerResponse.stringBody "Hello anonymous!")
]
greet : ApiRoute ApiRoute.Response
greet =
ApiRoute.succeed
@ -46,7 +69,7 @@ greet =
field "first"
)
]
|> Server.Request.thenRespond
|> Server.Request.map
(\firstName ->
ServerResponse.stringBody ("Hello " ++ firstName)
|> DataSource.succeed
@ -65,7 +88,7 @@ fileLength =
(\{ field, optionalField, fileField } ->
fileField "file"
)
|> Server.Request.thenRespond
|> Server.Request.map
(\file ->
ServerResponse.json
(Json.Encode.object
@ -94,12 +117,10 @@ fileLength =
redirectRoute : ApiRoute ApiRoute.Response
redirectRoute =
ApiRoute.succeed
(Server.Request.succeed ()
|> Server.Request.thenRespond
(\() ->
DataSource.succeed
(ServerResponse.temporaryRedirect "/")
)
(Server.Request.succeed
(DataSource.succeed
(ServerResponse.temporaryRedirect "/")
)
)
|> ApiRoute.literal "api"
|> ApiRoute.slash
@ -128,21 +149,19 @@ serverRequestDataSource isAvailable =
noArgs : ApiRoute ApiRoute.Response
noArgs =
ApiRoute.succeed
(Server.Request.succeed ()
|> Server.Request.thenRespond
(\() ->
DataSource.Http.get
(Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(Decode.field "stargazers_count" Decode.int)
|> DataSource.map
(\stars ->
Json.Encode.object
[ ( "repo", Json.Encode.string "elm-pages" )
, ( "stars", Json.Encode.int stars )
]
|> ServerResponse.json
)
)
(Server.Request.succeed
(DataSource.Http.get
(Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(Decode.field "stargazers_count" Decode.int)
|> DataSource.map
(\stars ->
Json.Encode.object
[ ( "repo", Json.Encode.string "elm-pages" )
, ( "stars", Json.Encode.int stars )
]
|> ServerResponse.json
)
)
)
|> ApiRoute.literal "api"
|> ApiRoute.slash
@ -179,20 +198,18 @@ nonHybridRoute =
logout : ApiRoute ApiRoute.Response
logout =
ApiRoute.succeed
(Server.Request.succeed ()
|> Server.Request.thenRespond
(\() ->
DataSource.succeed
(ServerResponse.stringBody "You are logged out"
|> ServerResponse.withHeader "Set-Cookie"
(SetCookie.setCookie "username" ""
|> SetCookie.httpOnly
|> SetCookie.withPath "/"
|> SetCookie.withImmediateExpiration
|> SetCookie.toString
)
(Server.Request.succeed
(DataSource.succeed
(ServerResponse.stringBody "You are logged out"
|> ServerResponse.withHeader "Set-Cookie"
(SetCookie.setCookie "username" ""
|> SetCookie.httpOnly
|> SetCookie.withPath "/"
|> SetCookie.withImmediateExpiration
|> SetCookie.toString
)
)
)
)
|> ApiRoute.literal "api"
|> ApiRoute.slash
@ -204,21 +221,19 @@ repoStars : ApiRoute ApiRoute.Response
repoStars =
ApiRoute.succeed
(\repoName ->
Server.Request.succeed ()
|> Server.Request.thenRespond
(\() ->
DataSource.Http.get
(Secrets.succeed ("https://api.github.com/repos/dillonkearns/" ++ repoName))
(Decode.field "stargazers_count" Decode.int)
|> DataSource.map
(\stars ->
Json.Encode.object
[ ( "repo", Json.Encode.string repoName )
, ( "stars", Json.Encode.int stars )
]
|> ServerResponse.json
)
)
Server.Request.succeed
(DataSource.Http.get
(Secrets.succeed ("https://api.github.com/repos/dillonkearns/" ++ repoName))
(Decode.field "stargazers_count" Decode.int)
|> DataSource.map
(\stars ->
Json.Encode.object
[ ( "repo", Json.Encode.string repoName )
, ( "stars", Json.Encode.int stars )
]
|> ServerResponse.json
)
)
)
|> ApiRoute.literal "api"
|> ApiRoute.slash

View File

@ -39,22 +39,19 @@ type alias Data =
Maybe Request.File
data : RouteParams -> Request.Handler (PageServerResponse Data)
data : RouteParams -> Request.ServerRequest (DataSource (PageServerResponse Data))
data routeParams =
Request.oneOfHandler
Request.oneOf
[ Request.expectMultiPartFormPost
(\{ field, optionalField, fileField } ->
fileField "file"
)
|> Request.thenRespond
|> Request.map
(\file ->
DataSource.succeed (PageServerResponse.RenderPage (Just file))
)
, Request.succeed ()
|> Request.thenRespond
(\() ->
DataSource.succeed (PageServerResponse.RenderPage Nothing)
)
, Request.succeed
(DataSource.succeed (PageServerResponse.RenderPage Nothing))
]

View File

@ -39,13 +39,13 @@ page =
|> Page.buildNoState { view = view }
data : RouteParams -> Request.Handler (PageServerResponse Data)
data : RouteParams -> Request.ServerRequest (DataSource (PageServerResponse Data))
data routeParams =
Request.oneOfHandler
Request.oneOf
[ Request.map2 Data
(Request.expectQueryParam "name")
Request.requestTime
|> Request.thenRespond
|> Request.map
(\requestData ->
requestData
|> PageServerResponse.RenderPage
@ -54,18 +54,16 @@ data routeParams =
, Request.map2 Data
(Request.expectCookie "username")
Request.requestTime
|> Request.thenRespond
|> Request.map
(\requestData ->
requestData
|> PageServerResponse.RenderPage
|> DataSource.succeed
)
, Request.succeed ()
|> Request.thenRespond
(\() ->
DataSource.succeed
(PageServerResponse.ServerResponse (ServerResponse.temporaryRedirect "/login"))
)
, Request.succeed
(DataSource.succeed
(PageServerResponse.ServerResponse (ServerResponse.temporaryRedirect "/login"))
)
]

View File

@ -44,11 +44,11 @@ type alias Request =
}
data : RouteParams -> Request.Handler (PageServerResponse Data)
data : RouteParams -> Request.ServerRequest (DataSource (PageServerResponse Data))
data routeParams =
Request.oneOfHandler
Request.oneOf
[ Request.expectFormPost (\{ field } -> field "name")
|> Request.thenRespond
|> Request.map
(\name ->
PageServerResponse.ServerResponse
("/greet"
@ -63,7 +63,7 @@ data routeParams =
|> DataSource.succeed
)
, Request.cookie "username"
|> Request.thenRespond
|> Request.map
(\name ->
name
|> Data

View File

@ -49,11 +49,11 @@ type alias LoggedInInfo =
}
data : RouteParams -> Request.Handler (PageServerResponse Data)
data : RouteParams -> Request.ServerRequest (DataSource (PageServerResponse Data))
data routeParams =
Request.oneOfHandler
Request.oneOf
[ Request.expectCookie "username"
|> Request.thenRespond
|> Request.map
(\username ->
username
|> LoggedInInfo
@ -62,18 +62,16 @@ data routeParams =
|> DataSource.map LoggedIn
|> DataSource.map PageServerResponse.RenderPage
)
, Request.succeed ()
|> Request.thenRespond
(\() ->
NotLoggedIn
|> DataSource.succeed
|> DataSource.map PageServerResponse.RenderPage
--"/login"
-- |> ServerResponse.temporaryRedirect
-- --|> ServerResponse.withStatusCode 404
-- |> PageServerResponse.ServerResponse
-- |> DataSource.succeed
)
, Request.succeed
(NotLoggedIn
|> DataSource.succeed
|> DataSource.map PageServerResponse.RenderPage
--"/login"
-- |> ServerResponse.temporaryRedirect
-- --|> ServerResponse.withStatusCode 404
-- |> PageServerResponse.ServerResponse
-- |> DataSource.succeed
)
]

View File

@ -95,10 +95,10 @@ type alias Request =
-- |> DataSource.map PageServerResponse.RenderPage
data : RouteParams -> Request.Handler (PageServerResponse Data)
data : RouteParams -> Request.ServerRequest (DataSource (PageServerResponse Data))
data routeParams =
Request.succeed ()
|> Request.thenRespond
|> Request.map
(\() ->
PageServerResponse.ServerResponse (ServerResponse.stringBody "Hello, this is a string")
|> DataSource.succeed

View File

@ -335,7 +335,7 @@ preRenderWithFallback { data, head, pages } =
{-| -}
serverRender :
{ data : routeParams -> Server.Request.Handler (PageServerResponse data)
{ data : routeParams -> Server.Request.ServerRequest (DataSource (PageServerResponse data))
, head : StaticPayload data routeParams -> List Head.Tag
}
-> Builder routeParams data

View File

@ -182,7 +182,7 @@ type alias Data =
${
serverRender
? `data : RouteParams -> Request.Handler (PageServerResponse Data)
? `data : RouteParams -> Request.ServerRequest (DataSource (PageServerResponse Data))
data routeParams =`
: withFallback
? `data : RouteParams -> DataSource (PageServerResponse Data)

View File

@ -87,7 +87,7 @@ stripTrailingSlash path =
{-| -}
serverRender : ApiRouteBuilder (Server.Request.Handler ServerResponse) constructor -> ApiRoute Response
serverRender : ApiRouteBuilder (Server.Request.ServerRequest (DataSource ServerResponse)) constructor -> ApiRoute Response
serverRender ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
ApiRoute
{ regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never

View File

@ -2,8 +2,7 @@ module Server.Request exposing
( ServerRequest(..)
, Method(..)
, succeed
, Handler, Handlers
, oneOfHandler, requestTime, thenRespond, optionalHeader, expectContentType, expectJsonBody, acceptMethod, jsonBodyResult
, requestTime, optionalHeader, expectContentType, expectJsonBody, acceptMethod, jsonBodyResult
, map, map2, oneOf, andMap
, expectQueryParam
, cookie, expectCookie
@ -162,33 +161,16 @@ succeed value =
ServerRequest (OptimizedDecoder.succeed ( Ok value, [] ))
{-| -}
type Handlers response
= Handlers response
{-| -}
type Handler response
= Handler (OptimizedDecoder.Decoder (Result ( ValidationError, List ValidationError ) (DataSource response)))
{-| TODO internal only
-}
getDecoder : Handler response -> OptimizedDecoder.Decoder (Result ( ValidationError, List ValidationError ) (DataSource response))
getDecoder (Handler decoder) =
getDecoder : ServerRequest (DataSource response) -> OptimizedDecoder.Decoder (Result ( ValidationError, List ValidationError ) (DataSource response))
getDecoder (ServerRequest decoder) =
decoder
{-| -}
thenRespond : (request -> DataSource response) -> ServerRequest request -> Handler response
thenRespond thenDataSource (ServerRequest requestDecoder) =
requestDecoder
|> OptimizedDecoder.map
(\( result, validationErrors ) ->
case ( result, validationErrors ) of
( Ok value, [] ) ->
value
|> thenDataSource
|> Ok
( Err fatalError, errors ) ->
@ -197,7 +179,6 @@ thenRespond thenDataSource (ServerRequest requestDecoder) =
( Ok _, firstError :: rest ) ->
Err ( firstError, rest )
)
|> Handler
type ValidationError
@ -275,18 +256,6 @@ oneOf serverRequests =
)
{-| -}
oneOfHandler : List (Handler a) -> Handler a
oneOfHandler serverRequests =
Handler
(oneOfInternalHandler []
(List.map
(\(Handler decoder) -> decoder)
serverRequests
)
)
{-| Decode an argument and provide it to a function in a decoder.
decoder : Decoder String