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.