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

Add support for registering handlers for different 404 routes #2217

Merged
merged 1 commit into from Jul 12, 2022

Conversation

aldas
Copy link
Contributor

@aldas aldas commented Jul 10, 2022

This PR adds support for registering handlers for 404 routes. Echo instance and group has now method
RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) *Route
which registers handler for given path. Path supports any/path parameters and can be static (which is little bit silly but we still support it)

Custom 404 handler has priority in router over global 404 handler and 405 handling logic.

Example:

e := echo.New()

e.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })

g := e.Group("/images")
g.RouteNotFound("/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })
// or
g.Add(echo.RouteNotFound, "/*", func(c echo.Context) error { return c.NoContent(http.StatusNotFound) })

so you would have 2 404handlers in this example:

  • /*
  • /images/*

Routing performance is not significantly affected by this feature.

Benchstat between current master branch and this branch.

x@x:~/code/echo$ benchstat benchmark_master2.txt benchmark_new2.txt 
name                                    old time/op    new time/op    delta
pkg:github.com/labstack/echo/v4 goos:linux goarch:amd64
BindbindDataWithTags-6                    11.1µs ± 1%    11.1µs ± 0%    ~     (p=0.130 n=8+8)
DefaultBinder_BindInt64_single-6           244ns ± 1%     243ns ± 1%    ~     (p=0.664 n=8+8)
ValueBinder_BindInt64_single-6            24.0ns ± 1%    23.8ns ± 1%    ~     (p=0.067 n=7+8)
RawFunc_Int64_single-6                    12.9ns ± 1%    13.1ns ± 1%  +1.29%  (p=0.001 n=7+7)
DefaultBinder_BindInt64_10_fields-6       2.30µs ± 1%    2.29µs ± 1%    ~     (p=0.168 n=8+8)
ValueBinder_BindInt64_10_fields-6          272ns ± 2%     275ns ± 1%  +1.32%  (p=0.021 n=8+8)
AllocJSONP-6                               417ns ± 2%     397ns ± 1%  -4.80%  (p=0.000 n=8+8)
AllocJSON-6                                280ns ± 1%     266ns ± 1%  -5.07%  (p=0.000 n=8+8)
AllocXML-6                                1.69µs ± 2%    1.72µs ± 2%  +1.75%  (p=0.007 n=8+7)
RealIPForHeaderXForwardFor-6              32.9ns ± 1%    32.6ns ± 1%  -0.93%  (p=0.043 n=8+7)
Context_Store-6                           54.8ns ± 1%    55.0ns ± 2%    ~     (p=0.895 n=8+8)
EchoStaticRoutes-6                        18.0µs ± 2%    17.1µs ± 2%  -4.70%  (p=0.000 n=8+8)
EchoStaticRoutesMisses-6                  17.9µs ± 2%    17.3µs ± 2%  -2.91%  (p=0.000 n=8+8)
EchoGitHubAPI-6                           31.7µs ± 1%    31.8µs ± 1%    ~     (p=0.442 n=8+8)
EchoGitHubAPIMisses-6                     31.5µs ± 1%    31.8µs ± 2%  +0.98%  (p=0.014 n=7+8)
EchoParseAPI-6                            2.04µs ± 1%    2.07µs ± 2%  +1.23%  (p=0.019 n=8+8)
RouterStaticRoutes-6                      14.2µs ± 1%    13.7µs ± 1%  -3.20%  (p=0.000 n=8+8)
RouterStaticRoutesMisses-6                 476ns ± 1%     479ns ± 1%    ~     (p=0.100 n=7+8)
RouterGitHubAPI-6                         24.6µs ± 1%    24.3µs ± 1%  -1.13%  (p=0.000 n=8+7)
RouterGitHubAPIMisses-6                    587ns ± 1%     584ns ± 2%    ~     (p=0.105 n=8+8)
RouterParseAPI-6                          1.29µs ± 1%    1.25µs ± 1%  -3.17%  (p=0.000 n=8+8)
RouterParseAPIMisses-6                     313ns ± 1%     315ns ± 1%    ~     (p=0.099 n=8+8)
RouterGooglePlusAPI-6                      823ns ± 1%     817ns ± 0%  -0.70%  (p=0.005 n=8+6)
RouterGooglePlusAPIMisses-6                470ns ± 1%     470ns ± 1%    ~     (p=0.702 n=8+8)
RouterParamsAndAnyAPI-6                   2.02µs ± 1%    2.01µs ± 1%  -0.85%  (p=0.007 n=8+8)
pkg:github.com/labstack/echo/v4/middleware goos:linux goarch:amd64
Gzip-6                                    22.9µs ± 1%    22.9µs ± 0%    ~     (p=0.613 n=8+7)
Decompress-6                              1.08µs ± 2%    1.14µs ± 6%  +5.18%  (p=0.014 n=8+8)
LoggerWithConfig_withoutMapFields-6       3.02µs ±15%    3.09µs ± 6%    ~     (p=0.755 n=8+6)
LoggerWithConfig_withMapFields-6          3.92µs ±26%    3.72µs ± 7%    ~     (p=0.505 n=8+8)
RateLimiterMemoryStore_1000-6             2.37µs ± 3%    2.36µs ± 0%    ~     (p=0.143 n=8+7)
RateLimiterMemoryStore_10000-6            2.45µs ± 1%    2.49µs ± 1%  +1.41%  (p=0.001 n=8+8)
RateLimiterMemoryStore_100000-6           4.23µs ± 4%    4.36µs ± 1%  +3.04%  (p=0.000 n=8+8)
RateLimiterMemoryStore_conc100_10000-6    29.2µs ± 3%    29.4µs ± 2%    ~     (p=0.645 n=8+8)
RequestLogger_withoutMapFields-6          1.43µs ±16%    1.55µs ±15%    ~     (p=0.130 n=8+8)
RequestLogger_withMapFields-6             2.81µs ±24%    2.97µs ±13%    ~     (p=0.161 n=8+8)

name                                    old alloc/op   new alloc/op   delta
pkg:github.com/labstack/echo/v4 goos:linux goarch:amd64
BindbindDataWithTags-6                    1.05kB ± 0%    1.05kB ± 0%    ~     (all equal)
DefaultBinder_BindInt64_single-6           16.0B ± 0%     16.0B ± 0%    ~     (all equal)
ValueBinder_BindInt64_single-6             0.00B          0.00B         ~     (all equal)
RawFunc_Int64_single-6                     0.00B          0.00B         ~     (all equal)
DefaultBinder_BindInt64_10_fields-6         216B ± 0%      216B ± 0%    ~     (all equal)
ValueBinder_BindInt64_10_fields-6          0.00B          0.00B         ~     (all equal)
AllocJSONP-6                                182B ± 2%      177B ± 2%  -2.75%  (p=0.002 n=8+8)
AllocJSON-6                                 114B ± 1%      111B ± 1%  -2.82%  (p=0.001 n=6+8)
AllocXML-6                                4.75kB ± 2%    4.82kB ± 2%  +1.49%  (p=0.013 n=8+8)
EchoStaticRoutes-6                         0.00B          0.00B         ~     (all equal)
EchoStaticRoutesMisses-6                   0.00B          0.00B         ~     (all equal)
EchoGitHubAPI-6                            0.00B          0.00B         ~     (all equal)
EchoGitHubAPIMisses-6                      0.00B          0.00B         ~     (all equal)
EchoParseAPI-6                             0.00B          0.00B         ~     (all equal)
RouterStaticRoutes-6                       0.00B          0.00B         ~     (all equal)
RouterStaticRoutesMisses-6                 0.00B          0.00B         ~     (all equal)
RouterGitHubAPI-6                          0.00B          0.00B         ~     (all equal)
RouterGitHubAPIMisses-6                    0.00B          0.00B         ~     (all equal)
RouterParseAPI-6                           0.00B          0.00B         ~     (all equal)
RouterParseAPIMisses-6                     0.00B          0.00B         ~     (all equal)
RouterGooglePlusAPI-6                      0.00B          0.00B         ~     (all equal)
RouterGooglePlusAPIMisses-6                0.00B          0.00B         ~     (all equal)
RouterParamsAndAnyAPI-6                    0.00B          0.00B         ~     (all equal)
pkg:github.com/labstack/echo/v4/middleware goos:linux goarch:amd64
Gzip-6                                    1.53kB ± 5%    1.53kB ± 3%    ~     (p=0.901 n=8+8)
Decompress-6                              4.66kB ± 0%    4.66kB ± 0%    ~     (all equal)
LoggerWithConfig_withoutMapFields-6       1.42kB ± 0%    1.42kB ± 0%    ~     (all equal)
LoggerWithConfig_withMapFields-6          1.89kB ± 0%    1.89kB ± 0%    ~     (all equal)
RequestLogger_withoutMapFields-6          1.34kB ± 0%    1.34kB ± 0%    ~     (all equal)
RequestLogger_withMapFields-6             3.00kB ± 0%    3.00kB ± 0%    ~     (all equal)

name                                    old allocs/op  new allocs/op  delta
pkg:github.com/labstack/echo/v4 goos:linux goarch:amd64
BindbindDataWithTags-6                      51.0 ± 0%      51.0 ± 0%    ~     (all equal)
DefaultBinder_BindInt64_single-6            2.00 ± 0%      2.00 ± 0%    ~     (all equal)
ValueBinder_BindInt64_single-6              0.00           0.00         ~     (all equal)
RawFunc_Int64_single-6                      0.00           0.00         ~     (all equal)
DefaultBinder_BindInt64_10_fields-6         13.0 ± 0%      13.0 ± 0%    ~     (all equal)
ValueBinder_BindInt64_10_fields-6           0.00           0.00         ~     (all equal)
AllocJSONP-6                                4.00 ± 0%      4.00 ± 0%    ~     (all equal)
AllocJSON-6                                 1.00 ± 0%      1.00 ± 0%    ~     (all equal)
AllocXML-6                                  10.0 ± 0%      10.0 ± 0%    ~     (all equal)
EchoStaticRoutes-6                          0.00           0.00         ~     (all equal)
EchoStaticRoutesMisses-6                    0.00           0.00         ~     (all equal)
EchoGitHubAPI-6                             0.00           0.00         ~     (all equal)
EchoGitHubAPIMisses-6                       0.00           0.00         ~     (all equal)
EchoParseAPI-6                              0.00           0.00         ~     (all equal)
RouterStaticRoutes-6                        0.00           0.00         ~     (all equal)
RouterStaticRoutesMisses-6                  0.00           0.00         ~     (all equal)
RouterGitHubAPI-6                           0.00           0.00         ~     (all equal)
RouterGitHubAPIMisses-6                     0.00           0.00         ~     (all equal)
RouterParseAPI-6                            0.00           0.00         ~     (all equal)
RouterParseAPIMisses-6                      0.00           0.00         ~     (all equal)
RouterGooglePlusAPI-6                       0.00           0.00         ~     (all equal)
RouterGooglePlusAPIMisses-6                 0.00           0.00         ~     (all equal)
RouterParamsAndAnyAPI-6                     0.00           0.00         ~     (all equal)
pkg:github.com/labstack/echo/v4/middleware goos:linux goarch:amd64
Gzip-6                                      16.0 ± 0%      16.0 ± 0%    ~     (all equal)
Decompress-6                                8.00 ± 0%      8.00 ± 0%    ~     (all equal)
LoggerWithConfig_withoutMapFields-6         21.0 ± 0%      21.0 ± 0%    ~     (all equal)
LoggerWithConfig_withMapFields-6            26.0 ± 0%      26.0 ± 0%    ~     (all equal)
RequestLogger_withoutMapFields-6            14.0 ± 0%      14.0 ± 0%    ~     (all equal)
RequestLogger_withMapFields-6               25.0 ± 0%      25.0 ± 0%    ~     (all equal)

@aldas aldas requested a review from lammel July 10, 2022 20:18
@codecov
Copy link

codecov bot commented Jul 10, 2022

Codecov Report

Merging #2217 (54b7f55) into master (9bf1e3c) will increase coverage by 0.03%.
The diff coverage is 96.29%.

@@            Coverage Diff             @@
##           master    #2217      +/-   ##
==========================================
+ Coverage   92.29%   92.33%   +0.03%     
==========================================
  Files          37       37              
  Lines        3102     3118      +16     
==========================================
+ Hits         2863     2879      +16     
  Misses        150      150              
  Partials       89       89              
Impacted Files Coverage Δ
router.go 96.71% <96.00%> (+0.13%) ⬆️
echo.go 95.19% <100.00%> (+0.01%) ⬆️
group.go 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9bf1e3c...54b7f55. Read the comment docs.

@aldas
Copy link
Contributor Author

aldas commented Jul 10, 2022

@lammel could you review this?

Copy link
Contributor

@lammel lammel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a code review. Tests are looking good.
Not sure this is always intuitive, but it allows for very flexible usecases and handling not found differently on parts of a routing tree.
LGTM!

@aldas aldas merged commit 690e339 into labstack:master Jul 12, 2022
@aldas aldas deleted the route_not_found branch July 12, 2022 19:03
@ganigeorgiev
Copy link

@aldas Could this also be added to the v5 branch?

@aldas
Copy link
Contributor Author

aldas commented Jul 15, 2022

@ganigeorgiev yes. I have been planning for some time to rebase v5 branch over master to get latest stuff. I am planning to do it
this weekend.

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.

None yet

3 participants