Wildcard routes swallow later literals #1

Open
opened 2026-08-11 09:53:05 +00:00 by reviewer · 4 comments
Owner

Declaring /files/*path before /files/health means the health route is never reached.

Minimal case:

let router = Router {
    Route("/files/*path")
    Route("/files/health")
}
router.match(URL(string: "https://x/files/health")!)  // matches the wildcard

I would expect the more specific pattern to win regardless of order.

Declaring `/files/*path` before `/files/health` means the health route is never reached. Minimal case: ```swift let router = Router { Route("/files/*path") Route("/files/health") } router.match(URL(string: "https://x/files/health")!) // matches the wildcard ``` I would expect the more specific pattern to win regardless of order.
Author
Owner

Reproduced. The matcher returns the first route that matches at all, so order is load-bearing in a way nothing documents.

Reproduced. The matcher returns the first route that matches at all, so order is load-bearing in a way nothing documents.
Author
Owner

Scoring each match by specificity — literals beat parameters, parameters beat wildcards — and taking the highest. Draft on feature/route-priorities.

Scoring each match by specificity — literals beat parameters, parameters beat wildcards — and taking the highest. Draft on `feature/route-priorities`.
Author
Owner

That reads well. One thought: two routes with the same score should keep declaration order rather than being arbitrary.

That reads well. One thought: two routes with the same score should keep declaration order rather than being arbitrary.
Author
Owner

Agreed, and that falls out of using a strict > when comparing. Added a test for it.

Agreed, and that falls out of using a strict `>` when comparing. Added a test for it.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
reviewer/atlas#1
No description provided.