Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overlapping catch-all and param segment #24

Merged
merged 6 commits into from
Jul 13, 2023

Conversation

tigerwill90
Copy link
Owner

@tigerwill90 tigerwill90 commented Jul 2, 2023

Earlier this year, the RFC: Route Overlapping was introduced to enhance the routing flexibility of the router by allowing overlapping of wildcard segments with static segments. The current rules, as outlined in the RFC, are as follows:

Rules

  1. Prioritize the more specific route:
    • If a catch-all or named route overlaps with a static route segment, the static segment should be prioritized.
  2. Allow only one named or catch-all route to overlap with a static route segment.
  3. Overlapping named parameters and catch-all parameters in the same segment is not allowed.
  4. Each HTTP method has its own tree, so overlapping routes with different methods are allowed.

For example, the following route configurations are allowed:

/*{filepath}
/static
/content/{id}
/content/articles/{id}
/content/news/{id}
/content/events/{id}

Proposition

While supporting overlapping named parameters, such as /users/{id}/book and /users/{name}, presents challenges, this new RFC aims to introduce the capability to overlap catch-all and named parameter segments (overlapping named parameters within the same segment remains prohibited at this stage).

As a result, the following route configurations would be allowed:

/*{filepath}
/{chain}/track
/users/uuid:{id}
/users/uuid:*{any}

New Rules

  • Static segments are always evaluated first.
  • A named parameter can only overlap with a catch-all parameter or static segments.
  • A catch-all parameter can only overlap with a named parameter or static segments.
  • When a named parameter overlaps with a catch-all parameter, the named parameter is evaluated first.
  • Each HTTP method has its own tree, so overlapping routes with different methods are allowed.

Priority example

Pattern /users/123/email

Route Matching order
/users/{id}/email 1
/users/{id}/{action} 2
/users/*{any} 3

Pattern /users/123/revoke

Route Matching order
/users/{id}/email no match
/users/{id}/{action} 1
/users/*{any} 2

Pattern /users/123/orders/5

Route Matching order
/users/{id}/email no match
/users/{id}/{action} no match
/users/*{any} 1

Performance comparaison

goos: linux
goarch: amd64
pkg: github.com/tigerwill90/fox
cpu: Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
                    │   old.txt    │               new.txt                │
                    │    sec/op    │    sec/op      vs base               │
StaticAll-16          11.01µ ±  2%    11.13µ ±  0%  +1.08% (p=0.019 n=10)
GithubParamsAll-16    86.16n ±  3%    92.61n ±  2%  +7.49% (p=0.000 n=10)
OverlappingRoute-16   98.58n ±  0%   103.15n ±  1%  +4.64% (p=0.000 n=10)
StaticParallel-16     10.04n ±  8%    10.48n ± 12%  +4.46% (p=0.015 n=10)
CatchAll-16           32.15n ±  1%    32.63n ±  2%       ~ (p=0.086 n=10)
CatchAllParallel-16   5.927n ± 20%    6.111n ± 14%       ~ (p=0.190 n=10)
MultiWriter-16        106.8n ±  1%    103.5n ±  2%  -3.14% (p=0.000 n=10)
geomean               346.1n          350.7n        +1.33%

The impact on performance is expected to be null for static route and minimal for wildcard route.

@codecov
Copy link

codecov bot commented Jul 2, 2023

Codecov Report

Merging #24 (a43a499) into master (ed06170) will increase coverage by 0.20%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master      #24      +/-   ##
==========================================
+ Coverage   86.42%   86.62%   +0.20%     
==========================================
  Files          12       12              
  Lines        1790     1787       -3     
==========================================
+ Hits         1547     1548       +1     
+ Misses        210      205       -5     
- Partials       33       34       +1     
Flag Coverage Δ
coverage.txt 86.62% <100.00%> (+0.20%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
context.go 89.57% <ø> (ø)
error.go 54.54% <ø> (ø)
node.go 74.04% <ø> (ø)
helpers.go 100.00% <100.00%> (ø)
tree.go 92.48% <100.00%> (-0.04%) ⬇️

... and 2 files with indirect coverage changes

@tigerwill90 tigerwill90 requested review from pawndev and 4nth0 July 2, 2023 15:42
@tigerwill90 tigerwill90 marked this pull request as ready for review July 5, 2023 22:36
@tigerwill90 tigerwill90 changed the title [WIP] Allow overlapping catch-all and param segment Allow overlapping catch-all and param segment Jul 5, 2023
@tigerwill90 tigerwill90 self-assigned this Jul 8, 2023
@tigerwill90 tigerwill90 merged commit 1620764 into master Jul 13, 2023
@tigerwill90 tigerwill90 deleted the feat/routing/overlapping-catchall-and-params branch July 13, 2023 18:11
@pawndev
Copy link
Collaborator

pawndev commented Jul 14, 2023

@tigerwill90 sorry, I didn't take time to review this one 🙈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants