Skip to content

Commit

Permalink
feat(router): improve log for ambigous routes
Browse files Browse the repository at this point in the history
When roaster finds two or more matching route definitions it will now
tell the developer which priority, specificity and pattern they have.

- add new function `router:add-specificity`
  this allows to sort by it and output it for debugging
- refactor function `router:route-specificity`
  - expects route definition with specificity set
  - rename to `router:sort-by-specificity-and-priority`
  • Loading branch information
Nico Verwer authored and line-o committed Jul 15, 2023
1 parent 173c320 commit 0db0468
Showing 1 changed file with 28 additions and 6 deletions.
34 changes: 28 additions & 6 deletions content/router.xql
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,24 @@ declare function router:route ($api-files as xs:string+, $lookup as function(xs:
$matching-routes
else (
(: if there are multiple matches, prefer the one matching the longest pattern and the highest priority :)
util:log("debug", "ambigous route: " || $request-data?path),
head(sort($matching-routes, (), router:route-specificity#1))
let $matching-routes-with-specificity := for-each($matching-routes, router:add-specificity#1)
return (
util:log("debug", map {
"ambiguous route" : $request-data?path,
"method" : $request-data?method,
"matching definitions" : array {
$matching-routes-with-specificity ! map {
"priority": .?priority,
"specificity": .?specificity,
"pattern": .?pattern
}
}
}),
head(
sort(
$matching-routes-with-specificity, (),
router:sort-by-specificity-and-priority#1))
)
)

return
Expand Down Expand Up @@ -190,13 +206,19 @@ declare %private function router:create-regex($path as xs:string) as xs:string {
"^/" || string-join($replaced, "/")
};

declare %private function router:add-specificity ($route as map(*)) as map(*) {
let $specificity := string-length( (: the longer the more specific :)
replace( (: normalize route specificity by replacing path params :)
$route?pattern, $router:path-parameter-matcher, "?"))

return map:put($route, "specificity", $specificity)
};

(:~
: Sort routes by specificity
:)
declare %private function router:route-specificity ($route as map(*)) as xs:integer+ {
replace($route?pattern, $router:path-parameter-matcher, "?") (: normalize route specificity by replacing path params :)
=> (function ($np as xs:string) { - string-length($np) })() (: sort descending :) (: the longer the more specific :)
,
declare %private function router:sort-by-specificity-and-priority ($route as map(*)) as xs:integer+ {
-$route?specificity, (: sort descending :) (: the longer the more specific :)
$route?priority (: sort ascending :)
};

Expand Down

0 comments on commit 0db0468

Please sign in to comment.