Cro’s HTTP router is great at declaring routes, but it doesn’t provide a first‑class way to reference those routes elsewhere in your app. Cro::HTTP::RouterUtils fills that gap: it lets you reference endpoints by name, build typed-safe paths, generate HTMX attributes, redirect to routes, and even call the underlying implementation.
- Stable references to routes by name (or auto‑named fallback)
- Typed
path()builder validates parameter types -
hx-attrs()renders HTMX attributes with the correct method and URL -
redirect-to()returns a Cro redirect to the endpoint -
call()invokes the route implementation directly (handy for tests) - Supports
includewith prefixes seamlessly
Repo: https://github.com/FCO/Cro-HTTP-RouterUtils
Install
zef install --depsonly . Quick Start
use Cro::HTTP::RouterUtils; my $app = route { # Name a route via a named sub get my sub greet-path('greet', $name) { content 'text/plain', "Hello, $name!" } # Use the endpoint by name get -> 'links' { my $ep = endpoints('greet-path'); content 'text/html', qq:to/END/ <a href="{ $ep.path(:name<alice>) }">alice</a> <a href="#" { $ep.hx-attrs(:name<bob>, :trigger<click>) }>bob</a> END } } Naming and Discovering Endpoints
- Named endpoints: give your route a function name and reference it with
endpoints('your-name'). - Auto‑named endpoints: when no name is provided, keys are generated from method and path signature, e.g.
get_greet.
# Auto-named get -> 'greet', Str :$name { 200 } endpoints('get_greet').path; # => "/greet" # Named get my sub greet-path('greet', $name) { "Hello, $name!" } endpoints('greet-path').path(:name<alice>); # => "/greet/alice" Includes with prefixes are supported transparently:
include external => other-routes; # /external prefix applied endpoints('external-ep1').method; # "GET" endpoints('external-ep1').path; # "/external/returns-ok" Typed Path Building
path(*%values) enforces your route’s typed parameters; missing or invalid values throw.
get my sub sum('sum', Int $a, Int $b) { $a + $b } my $ep = endpoints('sum'); $ep.path(:a(1), :b(2)); # "/sum/1/2" $ep.path(:a("x"), :b(2)); # throws (type mismatch) $ep.path(:a(1)); # throws (missing parameter) HTMX Helpers
hx-attrs(:args…) returns a space-separated string of HTMX attributes. It uses the endpoint’s HTTP method by default (e.g., hx-get) and the built URL.
<a href="#" { endpoints('greet-path').hx-attrs( :name<alice>, :trigger<click>, :target<#out>, :swap<'outerHTML settle:200ms'>, :push-url<true>, :on{ click => "console.log(\"clicked\")" } ) }> Load Alice </a> Highlights supported:
- Request URL/method:
methodoverride; parameters via:name<...>etc. - Core:
trigger,target,confirm,indicator,swap,oob(ashx-swap-oob),boost - Navigation:
push-url(Bool|Str),replace-url(Bool|Str) - Selection:
select,select-oob - JSON:
vals,headers,request - Flags:
disable,validate - Misc:
disabled-elt,disinherit,encoding,ext,history,history-elt,include,inherit,params,prompt,sync,vars(deprecated) - Events:
:on{ event => "code" }emitshx-on:event='code'
Example minimal output:
hx-get='/greet/alice' hx-trigger='click' hx-target='#out' Redirects
get -> 'redir' { endpoints('greet-path').redirect-to: :name<ok> } Calling the Implementation
call(|args) invokes the underlying route implementation. Literal path segments are auto-injected; you pass only the non-literal parameters.
get my sub ret('ret') { 42 } get my sub sum('sum', Int $a, Int $b) { $a + $b } endpoints('ret').call; # 42 endpoints('sum').call(2, 3); # 5 Great for unit tests of pure route logic. If you depend on Cro’s pipeline, prefer Cro::HTTP::Test.
Full Example
See examples/example.raku and examples/ExampleRoute.rakumod in the repo. Run:
raku examples/example.raku Then visit:
-
/formfor a classic form -
/linksfor<a href>links built from endpoints -
/links-htmxfor HTMX-driven links
Errors and Guarantees
- Unknown endpoint name: throws.
- Missing/invalid path params: throws with a clear message.
-
call()auto-injects literal path segments; you provide the rest.
Why This Isn’t in Cro
Cro focuses on routing and request handling. This utility adds “endpoint as a value” ergonomics—stable references, typed path building, HTMX helpers, and redirect/call helpers—while staying a thin layer on top of Cro::HTTP::Router.
Appendix: Include With Prefix Example
# examples/ExampleRoute.rakumod use Cro::HTTP::RouterUtils; sub other-routes is export { route { get my sub external-ep1("returns-ok") { content "text/plain", "OK" } post my sub external-ep2("using-post") { content "text/plain", "OK" } } } # elsewhere include external => other-routes; endpoints('external-ep1').path; # "/external/returns-ok" endpoints('external-ep2').path; # "/external/using-post" —
Made with Cro::HTTP::RouterUtils (Raku).
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.