5c9f8ac85321ff855b0e939c3c40295bda5131ca
axon
WIP
HTTP server library inspired by axum, allowing best-in-class
expressive routing.
root :: Get -> Path "/" _ -> Aff String
root _ _ = pure "Hello, world!"
main :: Effect Unit
main = Axon.serve (root `Handle.or` Handle.Default.notFound)
-- GET localhost:8000/ -> 200 OK "Hello, world!"
-- GET localhost:8000/foo -> 404 Not Found
Request Handlers
Request handler functions have any number of parameters that are RequestParts and return an Aff Response (or any MonadAff).
RequestParts
RequestPartsRequest- Always succeeds; provides the entire request
- Combinators
Unit- Always succeeds
a /\ b- Tuple of
aandb, whereaandbareRequestParts.
- Tuple of
Maybe aamust beRequestParts. Ifacan't be extracted, the handler will still succeed and this will beNothing. Ifawas extracted, it's wrapped inJust.
Either a baandbmust beRequestParts. Succeeds if eitheraorbsucceeds (preferringa). Fails if both fail.
- Body
String- succeeds when request has a non-empty body that is valid UTF-8
Json a- succeeds when request has a
Stringbody (see above) that can be parsed intoausingDecodeJson.
- succeeds when request has a
Buffer- succeeds when request has a nonempty body.
Stream- succeeds when request has a nonempty body.
- Headers
Header aamust beTypedHeaderfromAxon.Header.Typed. Allows statically (ex.ContentType Type.MIME.Json) or dynamically (ex.ContentType String) matching request headers.
HeaderMap- All headers provided in the request
- Path
Path a c- Statically match the path of the request, and extract parameters. See
Axon.Request.Parts.Path. (TODO: this feels too magical, maybe follow axum's prior art of baking paths into the router declaration?)
- Statically match the path of the request, and extract parameters. See
- Method
GetPostPutPatchDeleteOptionsConnectTrace
Similarly to the structural extraction of request parts; handlers can use Axon.Response.Construct.ToResponse for easily constructing responses.
ToResponse
ToResponse- Combinators
Status /\ a- Special case to make sure any
Statusin a tuple will take priority over any default statuses within. TODO: This case (overlapping witha /\ brequires the class to be "sealed" in an instance chain. Want a clean way around this so consumers can implementToResponse.)
- Special case to make sure any
a /\ b- Merges
toResponse aandtoResponse b, usingbon conflicts
- Merges
- Status
Axon.Response.Status.Status
- Body
Axon.Response.Body.BodyStringNode.Buffer.BufferNode.Stream.Readable a(for alla)Axon.Response.Construct.Json aamust beEncodeJson. This will set the body toastringified, and setContent-Typetoapplication/json.
- Headers
ToResponseis implemented for all implementors ofTypedHeader- TODO:
Map String String
Description
Languages
PureScript
96.4%
JavaScript
3.6%