Add catchAll route and update documentation
This commit is contained in:
parent
99df474f93
commit
8375ce788b
@ -8,6 +8,7 @@
|
||||
* [Adding further types](#adding-further-types)
|
||||
* [Composing routes](#composing-routes)
|
||||
* [Reverse routing](#reverse-routing)
|
||||
* [Catch-all route](#catch-all-route)
|
||||
* [Working with request headers](#working-with-request-headers)
|
||||
|
||||
## Routing introduction
|
||||
@ -244,6 +245,51 @@ main = serve { port: 8080 } { route, router }
|
||||
redirect = headers [ Tuple "Location" $ print route $ New account ]
|
||||
```
|
||||
|
||||
### Catch-all route
|
||||
|
||||
You can easily create a catch all route by using the predefined `catchAll`.
|
||||
|
||||
```purescript
|
||||
import HTTPurple
|
||||
|
||||
data Route = CatchAll (Array String) -- list of paths
|
||||
derive instance Generic Route _
|
||||
|
||||
route :: RouteDuplex' Route
|
||||
route = mkRoute
|
||||
{ "CatchAll": catchAll
|
||||
}
|
||||
|
||||
main :: ServerM
|
||||
main = serve {} { route, router }
|
||||
where
|
||||
router { route: CatchAll paths } = ok $ "hello 🗺!"
|
||||
```
|
||||
|
||||
### Routing prefixes
|
||||
|
||||
You can create a route prefix such as `/v1/` using the `prefix` method. Here is an example:
|
||||
|
||||
```purescript
|
||||
import HTTPurple
|
||||
|
||||
data Route = Home -- list of paths
|
||||
derive instance Generic Route _
|
||||
|
||||
route :: RouteDuplex' Route
|
||||
route = root $ prefix "v1" $ sum
|
||||
{ "Home": noArgs
|
||||
}
|
||||
|
||||
main :: ServerM
|
||||
main = serve {} { route, router }
|
||||
where
|
||||
router { route: Home } = ok $ "hello 🗺!"
|
||||
```
|
||||
|
||||
Now all requests need to be prefixed with `/v1/`.
|
||||
|
||||
**Note**: `prefix` takes exactly one path segment. If you need two prefixes, e.g. for `/api/v1/` you need to use two prefixes: `root $ prefix "api" $ prefix "v1" $ sum`.
|
||||
|
||||
## Matching HTTP Methods
|
||||
|
||||
|
@ -30,7 +30,7 @@ import HTTPurple.Path (Path)
|
||||
import HTTPurple.Query (Query)
|
||||
import HTTPurple.Request (Request, fullPath)
|
||||
import HTTPurple.Response (Response, ResponseM, accepted, accepted', alreadyReported, alreadyReported', badGateway, badGateway', badRequest, badRequest', conflict, conflict', continue, continue', created, created', emptyResponse, emptyResponse', expectationFailed, expectationFailed', failedDependency, failedDependency', forbidden, forbidden', found, found', gatewayTimeout, gatewayTimeout', gone, gone', hTTPVersionNotSupported, hTTPVersionNotSupported', iMUsed, iMUsed', imATeapot, imATeapot', insufficientStorage, insufficientStorage', internalServerError, internalServerError', lengthRequired, lengthRequired', locked, locked', loopDetected, loopDetected', methodNotAllowed, methodNotAllowed', misdirectedRequest, misdirectedRequest', movedPermanently, movedPermanently', multiStatus, multiStatus', multipleChoices, multipleChoices', networkAuthenticationRequired, networkAuthenticationRequired', noContent, noContent', nonAuthoritativeInformation, nonAuthoritativeInformation', notAcceptable, notAcceptable', notExtended, notExtended', notFound, notFound', notImplemented, notImplemented', notModified, notModified', ok, ok', partialContent, partialContent', payloadTooLarge, payloadTooLarge', paymentRequired, paymentRequired', permanentRedirect, permanentRedirect', preconditionFailed, preconditionFailed', preconditionRequired, preconditionRequired', processing, processing', proxyAuthenticationRequired, proxyAuthenticationRequired', rangeNotSatisfiable, rangeNotSatisfiable', requestHeaderFieldsTooLarge, requestHeaderFieldsTooLarge', requestTimeout, requestTimeout', resetContent, resetContent', response, response', seeOther, seeOther', serviceUnavailable, serviceUnavailable', switchingProtocols, switchingProtocols', temporaryRedirect, temporaryRedirect', tooManyRequests, tooManyRequests', uRITooLong, uRITooLong', unauthorized, unauthorized', unavailableForLegalReasons, unavailableForLegalReasons', unprocessableEntity, unprocessableEntity', unsupportedMediaType, unsupportedMediaType', upgradeRequired, upgradeRequired', useProxy, useProxy', variantAlsoNegotiates, variantAlsoNegotiates')
|
||||
import HTTPurple.Routes (type (<+>), combineRoutes, mkRoute, orElse, (<+>))
|
||||
import HTTPurple.Routes (type (<+>), combineRoutes, mkRoute, orElse, (<+>), catchAll)
|
||||
import HTTPurple.Server (ServerM, serve)
|
||||
import HTTPurple.Status (Status)
|
||||
import HTTPurple.Validation (fromValidated, fromValidatedE)
|
||||
|
@ -1,10 +1,12 @@
|
||||
module HTTPurple.Routes
|
||||
( (<+>)
|
||||
, catchAll
|
||||
, combineRoutes
|
||||
, mkRoute
|
||||
, orElse
|
||||
, type (<+>)
|
||||
) where
|
||||
)
|
||||
where
|
||||
|
||||
import Prelude
|
||||
|
||||
@ -19,8 +21,10 @@ import Routing.Duplex as RD
|
||||
import Routing.Duplex.Generic as RG
|
||||
import Type.Proxy (Proxy(..))
|
||||
|
||||
-- | Type-level operator two combine two route definitions.
|
||||
infixr 0 type Either as <+>
|
||||
|
||||
-- | Combine two routes
|
||||
combineRoutes ::
|
||||
forall left right.
|
||||
RD.RouteDuplex' left ->
|
||||
@ -31,8 +35,10 @@ combineRoutes (RD.RouteDuplex lEnc lDec) (RD.RouteDuplex rEnc rDec) = (RD.RouteD
|
||||
enc = lEnc ||| rEnc
|
||||
dec = (lDec <#> Left) <|> (rDec <#> Right)
|
||||
|
||||
-- | Infix operator for `orElse`
|
||||
infixr 3 combineRoutes as <+>
|
||||
|
||||
-- | Combine two request handlers.
|
||||
orElse ::
|
||||
forall left right.
|
||||
(Request left -> ResponseM) ->
|
||||
@ -42,6 +48,7 @@ orElse ::
|
||||
orElse leftRouter _ request@{ route: Left l } = leftRouter $ Record.set (Proxy :: _ "route") l request
|
||||
orElse _ rightRouter request@{ route: Right r } = rightRouter $ Record.set (Proxy :: _ "route") r request
|
||||
|
||||
-- | Make a route from a `RoudeDuplex` definition.
|
||||
mkRoute ::
|
||||
forall i iGen r.
|
||||
Generic i iGen =>
|
||||
@ -49,3 +56,7 @@ mkRoute ::
|
||||
Record r ->
|
||||
RD.RouteDuplex i i
|
||||
mkRoute = RD.root <<< RG.sum
|
||||
|
||||
-- | A catch-all route that matches any request.
|
||||
catchAll :: RD.RouteDuplex' (Array String)
|
||||
catchAll = RD.many RD.segment
|
||||
|
Loading…
Reference in New Issue
Block a user