Skip to content

Commit 24fd165

Browse files
balcierenefectnReneWerner87
authored
✨ v3 (feature): new mounting system (#2022)
* 🔥 chore: removed mount from router * ✨ feat: new mounting system * ✨ feat: mount for group * ✅ test: updated and improve for new mount system * ♻️ refactor: better variable name * ♻️ refactor: better function naming * 🐛 fix: not mounted check * ✅ test: update onmount test if sub app is not mounted to parent * 🎨 perf: fix allocs problem * ✅ test: add benchmark for MountPath * ✨ feat: access to app's mountpath * ✅ test: remove parent app's mountpath test * remove some parts * add comment * fix Co-authored-by: Muhammed Efe Çetin <[email protected]> Co-authored-by: RW <[email protected]>
1 parent 709e095 commit 24fd165

File tree

6 files changed

+82
-47
lines changed

6 files changed

+82
-47
lines changed

app.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -618,33 +618,50 @@ func (app *App) GetRoutes(filterUseOption ...bool) []Route {
618618

619619
// Use registers a middleware route that will match requests
620620
// with the provided prefix (which is optional and defaults to "/").
621+
// Also, you can pass another app instance as a sub-router along a routing path.
622+
// It's very useful to split up a large API as many independent routers and
623+
// compose them as a single service using Use. The fiber's error handler and
624+
// any of the fiber's sub apps are added to the application's error handlers
625+
// to be invoked on errors that happen within the prefix route.
621626
//
622-
// app.Use(func(c fiber.Ctx) error {
623-
// return c.Next()
624-
// })
625-
// app.Use("/api", func(c fiber.Ctx) error {
626-
// return c.Next()
627-
// })
628-
// app.Use("/api", handler, func(c fiber.Ctx) error {
629-
// return c.Next()
630-
// })
627+
// app.Use(func(c fiber.Ctx) error {
628+
// return c.Next()
629+
// })
630+
// app.Use("/api", func(c fiber.Ctx) error {
631+
// return c.Next()
632+
// })
633+
// app.Use("/api", handler, func(c fiber.Ctx) error {
634+
// return c.Next()
635+
// })
636+
// subApp := fiber.New()
637+
// app.Use("/mounted-path", subApp)
631638
//
632639
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
633640
func (app *App) Use(args ...any) Router {
634641
var prefix string
642+
var subApp *App
635643
var handlers []Handler
636644

637645
for i := 0; i < len(args); i++ {
638646
switch arg := args[i].(type) {
639647
case string:
640648
prefix = arg
649+
case *App:
650+
subApp = arg
641651
case Handler:
642652
handlers = append(handlers, arg)
643653
default:
644654
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
645655
}
646656
}
657+
658+
if subApp != nil {
659+
app.mount(prefix, subApp)
660+
return app
661+
}
662+
647663
app.register([]string{methodUse}, prefix, nil, handlers...)
664+
648665
return app
649666
}
650667

group.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,50 @@ func (grp *Group) Name(name string) Router {
3939

4040
// Use registers a middleware route that will match requests
4141
// with the provided prefix (which is optional and defaults to "/").
42+
// Also, you can pass another app instance as a sub-router along a routing path.
43+
// It's very useful to split up a large API as many independent routers and
44+
// compose them as a single service using Use. The fiber's error handler and
45+
// any of the fiber's sub apps are added to the application's error handlers
46+
// to be invoked on errors that happen within the prefix route.
4247
//
43-
// app.Use(func(c fiber.Ctx) error {
44-
// return c.Next()
45-
// })
46-
// app.Use("/api", func(c fiber.Ctx) error {
47-
// return c.Next()
48-
// })
49-
// app.Use("/api", handler, func(c fiber.Ctx) error {
50-
// return c.Next()
51-
// })
48+
// app.Use(func(c fiber.Ctx) error {
49+
// return c.Next()
50+
// })
51+
// app.Use("/api", func(c fiber.Ctx) error {
52+
// return c.Next()
53+
// })
54+
// app.Use("/api", handler, func(c fiber.Ctx) error {
55+
// return c.Next()
56+
// })
57+
// subApp := fiber.New()
58+
// app.Use("/mounted-path", subApp)
5259
//
5360
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
5461
func (grp *Group) Use(args ...any) Router {
5562
prefix := ""
63+
var subApp *App
5664
var handlers []Handler
65+
5766
for i := 0; i < len(args); i++ {
5867
switch arg := args[i].(type) {
5968
case string:
6069
prefix = arg
70+
case *App:
71+
subApp = arg
6172
case Handler:
6273
handlers = append(handlers, arg)
6374
default:
6475
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
6576
}
6677
}
78+
79+
if subApp != nil {
80+
grp.mount(prefix, subApp)
81+
return grp
82+
}
83+
6784
grp.app.register([]string{methodUse}, getGroupPath(grp.Prefix, prefix), nil, handlers...)
85+
6886
return grp
6987
}
7088

hooks_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ func Test_Hook_OnRoute(t *testing.T) {
3030
subApp := New()
3131
subApp.Get("/test", testSimpleHandler)
3232

33-
app.Mount("/sub", subApp)
33+
app.Use("/sub", subApp)
3434
}
3535

3636
func Test_Hook_OnRoute_Mount(t *testing.T) {
3737
t.Parallel()
3838

3939
app := New()
4040
subApp := New()
41-
app.Mount("/sub", subApp)
41+
app.Use("/sub", subApp)
4242

4343
subApp.Hooks().OnRoute(func(r Route) error {
4444
require.Equal(t, "/sub/test", r.Path)
@@ -77,7 +77,7 @@ func Test_Hook_OnName(t *testing.T) {
7777
subApp.Get("/test", testSimpleHandler)
7878
subApp.Get("/test2", testSimpleHandler)
7979

80-
app.Mount("/sub", subApp)
80+
app.Use("/sub", subApp)
8181

8282
require.Equal(t, "index", buf.String())
8383
}
@@ -124,7 +124,7 @@ func Test_Hook_OnGroup_Mount(t *testing.T) {
124124

125125
app := New()
126126
micro := New()
127-
micro.Mount("/john", app)
127+
micro.Use("/john", app)
128128

129129
app.Hooks().OnGroup(func(g Group) error {
130130
require.Equal(t, "/john/v1", g.Prefix)
@@ -255,5 +255,5 @@ func Test_Hook_OnMount(t *testing.T) {
255255
return nil
256256
})
257257

258-
app.Mount("/sub", subApp)
258+
app.Use("/sub", subApp)
259259
}

mount.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func newMountFields(app *App) *mountFields {
3636
// compose them as a single service using Mount. The fiber's error handler and
3737
// any of the fiber's sub apps are added to the application's error handlers
3838
// to be invoked on errors that happen within the prefix route.
39-
func (app *App) Mount(prefix string, fiber *App) Router {
39+
func (app *App) mount(prefix string, fiber *App) Router {
4040
prefix = strings.TrimRight(prefix, "/")
4141
if prefix == "" {
4242
prefix = "/"
@@ -58,8 +58,10 @@ func (app *App) Mount(prefix string, fiber *App) Router {
5858

5959
// Mount attaches another app instance as a sub-router along a routing path.
6060
// It's very useful to split up a large API as many independent routers and
61-
// compose them as a single service using Mount.
62-
func (grp *Group) Mount(prefix string, fiber *App) Router {
61+
// compose them as a single service using Mount. The fiber's error handler and
62+
// any of the fiber's sub apps are added to the application's error handlers
63+
// to be invoked on errors that happen within the prefix route.
64+
func (grp *Group) mount(prefix string, fiber *App) Router {
6365
groupPath := getGroupPath(grp.Prefix, prefix)
6466
groupPath = strings.TrimRight(groupPath, "/")
6567
if groupPath == "" {

mount_test.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func Test_App_Mount(t *testing.T) {
2121
})
2222

2323
app := New()
24-
app.Mount("/john", micro)
24+
app.Use("/john", micro)
2525
resp, err := app.Test(httptest.NewRequest(MethodGet, "/john/doe", nil))
2626
require.Equal(t, nil, err, "app.Test(req)")
2727
require.Equal(t, 200, resp.StatusCode, "Status code")
@@ -35,9 +35,9 @@ func Test_App_Mount_Nested(t *testing.T) {
3535
two := New()
3636
three := New()
3737

38-
two.Mount("/three", three)
39-
app.Mount("/one", one)
40-
one.Mount("/two", two)
38+
two.Use("/three", three)
39+
app.Use("/one", one)
40+
one.Use("/two", two)
4141

4242
one.Get("/doe", func(c Ctx) error {
4343
return c.SendStatus(StatusOK)
@@ -73,9 +73,9 @@ func Test_App_MountPath(t *testing.T) {
7373
two := New()
7474
three := New()
7575

76-
two.Mount("/three", three)
77-
one.Mount("/two", two)
78-
app.Mount("/one", one)
76+
two.Use("/three", three)
77+
one.Use("/two", two)
78+
app.Use("/one", one)
7979

8080
require.Equal(t, "/one", one.MountPath())
8181
require.Equal(t, "/one/two", two.MountPath())
@@ -96,7 +96,7 @@ func Test_App_ErrorHandler_GroupMount(t *testing.T) {
9696

9797
app := New()
9898
v1 := app.Group("/v1")
99-
v1.Mount("/john", micro)
99+
v1.Use("/john", micro)
100100

101101
resp, err := app.Test(httptest.NewRequest(MethodGet, "/v1/john/doe", nil))
102102
testErrorResponse(t, err, resp, "1: custom error")
@@ -115,7 +115,7 @@ func Test_App_ErrorHandler_GroupMountRootLevel(t *testing.T) {
115115

116116
app := New()
117117
v1 := app.Group("/v1")
118-
v1.Mount("/", micro)
118+
v1.Use("/", micro)
119119

120120
resp, err := app.Test(httptest.NewRequest(MethodGet, "/v1/john/doe", nil))
121121
testErrorResponse(t, err, resp, "1: custom error")
@@ -130,7 +130,7 @@ func Test_App_Group_Mount(t *testing.T) {
130130

131131
app := New()
132132
v1 := app.Group("/v1")
133-
v1.Mount("/john", micro)
133+
v1.Use("/john", micro)
134134

135135
resp, err := app.Test(httptest.NewRequest(MethodGet, "/v1/john/doe", nil))
136136
require.Equal(t, nil, err, "app.Test(req)")
@@ -150,7 +150,7 @@ func Test_App_UseMountedErrorHandler(t *testing.T) {
150150
return errors.New("something happened")
151151
})
152152

153-
app.Mount("/api", fiber)
153+
app.Use("/api", fiber)
154154

155155
resp, err := app.Test(httptest.NewRequest(MethodGet, "/api", nil))
156156
testErrorResponse(t, err, resp, "hi, i'm a custom error")
@@ -168,7 +168,7 @@ func Test_App_UseMountedErrorHandlerRootLevel(t *testing.T) {
168168
return errors.New("something happened")
169169
})
170170

171-
app.Mount("/", fiber)
171+
app.Use("/", fiber)
172172

173173
resp, err := app.Test(httptest.NewRequest(MethodGet, "/api", nil))
174174
testErrorResponse(t, err, resp, "hi, i'm a custom error")
@@ -196,7 +196,7 @@ func Test_App_UseMountedErrorHandlerForBestPrefixMatch(t *testing.T) {
196196
subfiber.Get("/", func(c Ctx) error {
197197
return errors.New("something happened")
198198
})
199-
subfiber.Mount("/third", tripleSubFiber)
199+
subfiber.Use("/third", tripleSubFiber)
200200

201201
f := func(c Ctx, err error) error {
202202
return c.Status(200).SendString("hi, i'm a custom error")
@@ -207,9 +207,9 @@ func Test_App_UseMountedErrorHandlerForBestPrefixMatch(t *testing.T) {
207207
fiber.Get("/", func(c Ctx) error {
208208
return errors.New("something happened")
209209
})
210-
fiber.Mount("/sub", subfiber)
210+
fiber.Use("/sub", subfiber)
211211

212-
app.Mount("/api", fiber)
212+
app.Use("/api", fiber)
213213

214214
resp, err := app.Test(httptest.NewRequest(MethodGet, "/api/sub", nil))
215215
require.Equal(t, nil, err, "/api/sub req")
@@ -246,7 +246,7 @@ func Test_Ctx_Render_Mount(t *testing.T) {
246246
})
247247

248248
app := New()
249-
app.Mount("/hello", sub)
249+
app.Use("/hello", sub)
250250

251251
resp, err := app.Test(httptest.NewRequest(MethodGet, "/hello/a", nil))
252252
require.Equal(t, StatusOK, resp.StatusCode, "Status code")
@@ -301,8 +301,8 @@ func Test_Ctx_Render_Mount_ParentOrSubHasViews(t *testing.T) {
301301
return c.Render("bruh.tmpl", Map{})
302302
})
303303

304-
sub.Mount("/bruh", sub2)
305-
app.Mount("/hello", sub)
304+
sub.Use("/bruh", sub2)
305+
app.Use("/hello", sub)
306306

307307
resp, err := app.Test(httptest.NewRequest(MethodGet, "/hello/world/a", nil))
308308
require.Equal(t, StatusOK, resp.StatusCode, "Status code")
@@ -348,7 +348,7 @@ func Test_Ctx_Render_MountGroup(t *testing.T) {
348348

349349
app := New()
350350
v1 := app.Group("/v1")
351-
v1.Mount("/john", micro)
351+
v1.Use("/john", micro)
352352

353353
resp, err := app.Test(httptest.NewRequest(MethodGet, "/v1/john/doe", nil))
354354
require.Equal(t, nil, err, "app.Test(req)")

router.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ type Router interface {
3838

3939
Route(path string) Register
4040

41-
Mount(prefix string, fiber *App) Router
42-
4341
Name(name string) Router
4442
}
4543

0 commit comments

Comments
 (0)