Skip to content

Add NewWithCustomCtx initialization helper #3476

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

Merged

Conversation

ReneWerner87
Copy link
Member

Summary

  • expose NewWithCustomCtx for creating apps with custom contexts
  • make context factory setter private
  • update tests and docs to use the new helper

Testing

  • go test ./...

@ReneWerner87 ReneWerner87 requested a review from a team as a code owner May 24, 2025 21:32
@ReneWerner87 ReneWerner87 requested review from gaby and sixcolors May 24, 2025 21:32
@ReneWerner87 ReneWerner87 requested a review from efectn May 24, 2025 21:32
Copy link
Contributor

coderabbitai bot commented May 24, 2025

Walkthrough

This change refactors Fiber's custom context handling by introducing a new constructor NewWithCustomCtx for initializing an app with a custom context factory in one step. It unifies request handler logic, removes redundant code paths, simplifies context and route matching, removes obsolete helper methods, and updates documentation and tests to reflect the new initialization approach.

Changes

File(s) Change Summary
app.go Added NewWithCustomCtx constructor; renamed and privatized NewCtxFunc to setCtxFunc; unified handler logic to always use requestHandler.
ctx.go Simplified Next() and RestartRouting() to always call unified next() method; removed conditional custom context logic.
ctx_test.go Updated tests to use NewWithCustomCtx instead of separate context setter method.
docs/api/app.md, docs/whats_new.md Renamed and replaced NewCtxFunc with NewWithCustomCtx in docs; updated examples and descriptions accordingly.
helpers.go Removed methodExist and methodExistCustom methods entirely.
router.go Swapped signatures of next and nextCustom; merged defaultRequestHandler and customRequestHandler into unified requestHandler; improved route matching and error handling.
ctx_interface.go Removed newCtx() method; updated AcquireCtx and ReleaseCtx to use CustomCtx interface exclusively.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant App
    participant CustomCtxFactory
    participant RequestHandler
    participant RouteStack

    User->>App: NewWithCustomCtx(customCtxFunc, config)
    App->>CustomCtxFactory: Store customCtxFunc
    User->>App: HTTP Request
    App->>RequestHandler: requestHandler(rctx)
    RequestHandler->>CustomCtxFactory: Create CustomCtx
    RequestHandler->>RouteStack: next(CustomCtx)
    RouteStack-->>RequestHandler: Handler execution result
    RequestHandler-->>App: Return response
Loading

Possibly related PRs

Suggested labels

🧹 Updates

Suggested reviewers

  • sixcolors
  • efectn

Poem

In Fiber's field, a context anew,
With one swift hop, a custom view!
No more split paths, no handler fuss,
Just one clean way for all of us.
Docs and tests now join the dance—
Rabbits cheer for this advance! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented May 24, 2025

Codecov Report

Attention: Patch coverage is 67.08861% with 52 lines in your changes missing coverage. Please review.

Project coverage is 90.67%. Comparing base (e1a7c11) to head (b8a0ed0).
Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
router.go 63.82% 46 Missing and 5 partials ⚠️
ctx_interface.go 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3476      +/-   ##
==========================================
+ Coverage   90.53%   90.67%   +0.13%     
==========================================
  Files         110      110              
  Lines       10949    10936      -13     
==========================================
+ Hits         9913     9916       +3     
+ Misses        777      769       -8     
+ Partials      259      251       -8     
Flag Coverage Δ
unittests 90.67% <67.08%> (+0.13%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ReneWerner87 ReneWerner87 requested a review from Copilot May 24, 2025 21:35
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a new helper, NewWithCustomCtx, to simplify initializing an app with a custom context while hiding the context factory setter.

  • Renames nextCustom to next and customRequestHandler to requestHandler for consistency.
  • Updates tests, documentation, and helper functions to reflect the new initialization process.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
router.go Renames methods and updates error message handling for custom contexts.
helpers.go Renames methodExistCustom to methodExist for consistency.
docs/whats_new.md Updates release notes to document NewWithCustomCtx.
docs/api/app.md Updates API documentation to reflect the new helper.
ctx_test.go Updates tests to use NewWithCustomCtx.
ctx.go Simplifies context handling by using the new next implementation.
app.go Introduces NewWithCustomCtx and refactors internal context handling.
Comments suppressed due to low confidence (1)

router.go:110

  • [nitpick] Renaming 'nextCustom' to 'next' may lead to ambiguity with similar methods handling DefaultCtx; consider a more descriptive name to differentiate custom and default context flows.
func (app *App) next(c CustomCtx) (bool, error) { //nolint:unparam // bool param might be useful for testing

@ReneWerner87
Copy link
Member Author

  • the performance still needs to be checked so that the process has not become slower

Copy link
Member

@gaby gaby left a comment

Choose a reason for hiding this comment

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

👍 LGTM, this heavily simplifies the router/ctx when using a CustomCtx.

@ReneWerner87
Copy link
Member Author

old:
image

new:
image

this is bad, i have to investigate why it took so long

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
router.go (1)

193-198: 🛠️ Refactor suggestion

Clarify error handling flow - TODO needs resolution.

The TODO comment questions whether to return after error handling. Currently, the function continues execution even after ErrorHandler processes an error and sends a status. This could lead to unexpected behavior if handlers modify the response after an error has been handled.

Consider returning immediately after error handling to prevent further processing:

 if err != nil {
     if catch := ctx.App().ErrorHandler(ctx, err); catch != nil {
         _ = ctx.SendStatus(StatusInternalServerError) //nolint:errcheck // Always return nil
     }
-    // TODO: Do we need to return here?
+    return
 }
♻️ Duplicate comments (1)
router.go (1)

110-168: Well-structured unification of routing logic, but performance impact needs investigation.

The consolidation of next and nextCustom into a single method using the CustomCtx interface is clean and reduces code duplication. However, according to the PR objectives, there's a noted performance degradation that needs to be investigated.

The interface method calls (getMethodInt(), getTreePathHash(), etc.) may introduce overhead compared to direct field access in the previous implementation.

🧹 Nitpick comments (2)
docs/whats_new.md (2)

68-69: Link to API docs for NewWithCustomCtx
To help users quickly find the full API details, consider hyperlinking this new method to the API reference, e.g.:

- **NewWithCustomCtx**: Initialize an app with a custom context in one step. See [API → App#NewWithCustomCtx](./api/app#newwithcustomctx).

93-98: Ensure consistent code fence metadata
This fence uses go title="Signature", but other code blocks don’t include titles. For consistency, either remove the title attribute here or add similar titles elsewhere.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c123ce and 40dea8e.

📒 Files selected for processing (7)
  • app.go (4 hunks)
  • ctx.go (1 hunks)
  • ctx_test.go (2 hunks)
  • docs/api/app.md (2 hunks)
  • docs/whats_new.md (4 hunks)
  • helpers.go (2 hunks)
  • router.go (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: unit (1.24.x, windows-latest)
  • GitHub Check: unit (1.23.x, windows-latest)
  • GitHub Check: Compare
  • GitHub Check: unit (1.23.x, macos-13)
  • GitHub Check: repeated
🔇 Additional comments (10)
helpers.go (1)

106-150: LGTM! Clean interface abstraction.

The refactoring from *DefaultCtx to CustomCtx interface is well-executed and maintains the same functionality while providing better abstraction. The use of interface methods like getMethodInt(), getTreePathHash(), and setIndexRoute() properly encapsulates the context operations.

ctx.go (2)

1048-1048: LGTM! Simplified routing logic.

The removal of conditional logic and direct call to c.app.next(c) aligns well with the unified request handling approach described in the PR summary.


1058-1058: LGTM! Consistent with the unified routing approach.

The change to always call c.app.next(c) maintains consistency with the Next() method and the broader refactoring goals.

However, please monitor the performance impact as mentioned in the PR objectives, since this consolidation might affect request handling performance.

docs/whats_new.md (1)

121-126: Example aligns with signature
The factory function correctly returns fiber.Ctx (satisfying the generic CustomCtx constraint), and the example embeds DefaultCtx properly. LGTM.

ctx_test.go (2)

134-140: Consistent API usage with proper Config integration.

The test correctly demonstrates using NewWithCustomCtx with additional configuration options, showing how the new API handles both custom context creation and app configuration in a unified manner.


112-116:

❓ Verification inconclusive

LGTM! Clean migration to the new API pattern.

The test correctly uses the new NewWithCustomCtx constructor, which consolidates app creation and custom context function registration into a single step. This aligns well with the PR objectives to introduce the new helper function.

However, given the performance concerns mentioned in the PR objectives, it would be valuable to verify that this change doesn't introduce performance regression in the test execution:


🏁 Script executed:

#!/bin/bash
# Description: Run specific custom context tests and measure performance
# Compare execution time of these tests to identify any performance impact

echo "Running custom context tests with timing..."
go test -run "Test_Ctx_CustomCtx" -v -count=5 -benchtime=1s

Length of output: 375


Please verify performance of the new NewWithCustomCtx tests
I’m unable to run the timing script in this environment (missing Go module), so please execute the following locally to ensure there’s no regression:

# From your module root:
go test -run "Test_Ctx_CustomCtx" -v -count=5 -benchtime=1s

Once you’ve confirmed performance is on par with the previous two-step initialization, this change can be considered fully approved.

app.go (4)

626-633: LGTM! Clean implementation of the custom context constructor.

The new NewWithCustomCtx function provides a convenient way to initialize an app with a custom context factory in a single call. The documentation clearly explains its purpose and relationship to the existing API.


654-663: Good refactoring: Method visibility and documentation are appropriate.

The renaming from NewCtxFunc to setCtxFunc and making it unexported aligns well with the new initialization pattern via NewWithCustomCtx. The method correctly updates the server handler when the server is already initialized.


915-915: Excellent simplification of the handler logic.

Removing the conditional logic and always returning app.requestHandler aligns perfectly with the unified routing approach. This makes the code cleaner and more maintainable.


1126-1126: Consistent simplification in server initialization.

The change to always set app.server.Handler = app.requestHandler is consistent with the unified handler approach throughout the codebase.

Comment on lines +515 to 522
## NewWithCustomCtx

`NewCtxFunc` allows you to customize the `ctx` struct as needed.
`NewWithCustomCtx` creates a new `*App` and sets the custom context factory
function at construction time.

```go title="Signature"
func (app *App) NewCtxFunc(function func(app *App) CustomCtx)
func NewWithCustomCtx(fn func(app *App) CustomCtx, config ...Config) *App
```
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Document generic type parameter in signature
The actual implementation of NewWithCustomCtx is generic over the custom context type (with a Ctx constraint), but the brackets around the type parameter are omitted here. Consider showing the full generic signature, for example:

func NewWithCustomCtx[CC Ctx](fn func(app *App) CC, config ...Config) *App
🤖 Prompt for AI Agents
In docs/api/app.md around lines 515 to 522, the function signature for
NewWithCustomCtx is missing the generic type parameter declaration. Update the
signature to include the generic type parameter with its constraint, for
example: func NewWithCustomCtx[CC Ctx](fn func(app *App) CC, config ...Config)
*App, to accurately reflect the implementation.

Comment on lines 541 to 546
func main() {
app := fiber.New()

app.NewCtxFunc(func(app *fiber.App) fiber.CustomCtx {
app := fiber.NewWithCustomCtx(func(app *fiber.App) fiber.CustomCtx {
return &CustomCtx{
DefaultCtx: *fiber.NewDefaultCtx(app),
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix incorrect return type in factory signature
The example’s factory function is declared as func(app *fiber.App) fiber.CustomCtx, but fiber.CustomCtx isn’t a defined type. It should match the local CustomCtx struct or the interface, e.g.:

app := fiber.NewWithCustomCtx(func(app *fiber.App) CustomCtx {
    return &CustomCtx{ DefaultCtx: *fiber.NewDefaultCtx(app) }
})

Or explicitly return the interface type:

func(app *fiber.App) fiber.Ctx { … }
🤖 Prompt for AI Agents
In docs/api/app.md around lines 541 to 546, the factory function passed to
fiber.NewWithCustomCtx has an incorrect return type fiber.CustomCtx, which is
not defined. Change the return type to either the local CustomCtx struct or the
fiber.Ctx interface to match the expected signature. For example, update the
function signature to func(app *fiber.App) *CustomCtx or func(app *fiber.App)
fiber.Ctx and ensure the returned value matches this type.

@sixcolors
Copy link
Member

IMO we could drop CustomContext in favor of #3382

@ReneWerner87
Copy link
Member Author

IMO we could drop CustomContext in favor of #3382

not really, one is the context.context and the other is the fiber context
both have different purpose

@sixcolors
Copy link
Member

sixcolors commented May 25, 2025

IMO we could drop CustomContext in favor of #3382

not really, one is the context.context and the other is the fiber context both have different purpose

Right, I totally mixed that up with v2 ctx.UserContext or v3 ctx. Context — too many different Contexts floating around, it’s hard to keep track! 😆

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 01c6c91 Previous: e1a7c11 Ratio
BenchmarkUnmarshaldata 10.42 ns/op 95.96 MB/s 0 B/op 0 allocs/op 5.293 ns/op 188.92 MB/s 0 B/op 0 allocs/op 1.97
BenchmarkUnmarshaldata - ns/op 10.42 ns/op 5.293 ns/op 1.97

This comment was automatically generated by workflow using github-action-benchmark.

@ReneWerner87
Copy link
Member Author

@ksw2000 Do you have any idea what the problem could be?
We are looking for 10ns in the next function compared to before
In the main branch it corresponds to the nextCustom to the next function

@ReneWerner87
Copy link
Member Author

Here some benchmarks for the functions

type benchCustomCtx struct {
    DefaultCtx
}

func (c *benchCustomCtx) Params(key string, defaultValue ...string) string { //revive:disable-line:unused-parameter
    return c.DefaultCtx.Params(key)
}

func newCustomApp() *App {
    return NewWithCustomCtx(func(app *App) CustomCtx {
        return &benchCustomCtx{DefaultCtx: *NewDefaultCtx(app)}
    })
}

func Benchmark_Next_Default(b *testing.B) {
    app := New()
    app.Get("/", func(_ Ctx) error { return nil })
    app.startupProcess()

    fctx := &fasthttp.RequestCtx{}
    fctx.Request.Header.SetMethod(MethodGet)
    fctx.Request.SetRequestURI("/")

    c, _ := app.AcquireCtx(fctx).(*DefaultCtx) //nolint:forcetypeassert // not needed
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        c.indexRoute = -1
        _, _ = app.next(c)
    }
}

func Benchmark_Next_Custom(b *testing.B) {
    app := newCustomApp()
    app.Get("/", func(_ Ctx) error { return nil })
    app.startupProcess()

    fctx := &fasthttp.RequestCtx{}
    fctx.Request.Header.SetMethod(MethodGet)
    fctx.Request.SetRequestURI("/")

    c := app.AcquireCtx(fctx).(CustomCtx)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        c.setIndexRoute(-1)
        _, _ = app.nextCustom(c)
    }
}

@ReneWerner87
Copy link
Member Author

* perf: modify app.pool

goos: darwin
goarch: arm64
pkg: github.com/gofiber/fiber/v3
cpu: Apple M4
                       │   old.txt   │              new.txt               │
                       │   sec/op    │   sec/op     vs base               │
_Communication_Flow-10   36.26n ± 0%   34.51n ± 0%  -4.83% (p=0.000 n=30)

                       │  old.txt   │            new.txt             │
                       │    B/op    │    B/op     vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

                       │  old.txt   │            new.txt             │
                       │ allocs/op  │ allocs/op   vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

* perf: optimize defaultCtx in app.next

```
goos: darwin
goarch: arm64
pkg: github.com/gofiber/fiber/v3
cpu: Apple M4
                       │   new.txt   │              new4.txt               │
                       │   sec/op    │   sec/op     vs base                │
_Communication_Flow-10   34.51n ± 0%   30.02n ± 0%  -13.01% (p=0.000 n=30)

                       │  new.txt   │            new4.txt            │
                       │    B/op    │    B/op     vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

                       │  new.txt   │            new4.txt            │
                       │ allocs/op  │ allocs/op   vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal
```

---------

Co-authored-by: Kashiwa <13825170+ksw2000@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
ctx_interface.go (1)

50-50: Fix inconsistent error message.

The error message mentions "failed to type-assert to Ctx" but the actual assertion is to CustomCtx. This inconsistency could confuse developers during debugging.

-		panic(errors.New("failed to type-assert to Ctx"))
+		panic(errors.New("failed to type-assert to CustomCtx"))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe01057 and 4bacc1a.

📒 Files selected for processing (4)
  • app.go (5 hunks)
  • ctx_interface.go (2 hunks)
  • helpers.go (0 hunks)
  • router.go (1 hunks)
💤 Files with no reviewable changes (1)
  • helpers.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • app.go
  • router.go
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: unit (1.24.x, macos-latest)
  • GitHub Check: unit (1.24.x, windows-latest)
  • GitHub Check: repeated
  • GitHub Check: unit (1.24.x, macos-13)
  • GitHub Check: Compare
🔇 Additional comments (1)
ctx_interface.go (1)

58-58: Parameter type change aligns with unified context approach.

The change from Ctx to CustomCtx parameter is consistent with the overall refactoring goal and maintains type safety.

@ReneWerner87
Copy link
Member Author

@efectn @gofiber/maintainers
with the conversion to “NewWithCustomCtx” we are hopefully in agreement

what do you think, should we go the old way with the double method (customRequestHandler + defaultRequestHandler, methodExist + methodExistCustom, nextCustom + next) or should we merge the current one, where the logic is merged in the method itself, but is a bit slower ?
image

ksw2000 referenced this pull request in ksw2000/fiber Jun 17, 2025
```
goos: darwin
goarch: arm64
pkg: github.com/gofiber/fiber/v3
cpu: Apple M4
                       │  head.txt   │            revert-1.txt            │
                       │   sec/op    │   sec/op     vs base               │
_Communication_Flow-10   30.04n ± 0%   28.74n ± 0%  -4.33% (p=0.000 n=30)

                       │  head.txt  │          revert-1.txt          │
                       │    B/op    │    B/op     vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

                       │  head.txt  │          revert-1.txt          │
                       │ allocs/op  │ allocs/op   vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal
```
@ksw2000
Copy link
Member

ksw2000 commented Jun 17, 2025

ReneWerner87

If we keep next and nextCustom separately, performance is not affected.

Please check this: ksw2000@6600202#commitcomment-160231393

I can make a pull request!

@efectn @gofiber/maintainers with the conversion to “NewWithCustomCtx” we are hopefully in agreement

what do you think, should we go the old way with the double method (customRequestHandler + defaultRequestHandler, methodExist + methodExistCustom, nextCustom + next) or should we merge the current one, where the logic is merged in the method itself, but is a bit slower ? image

@ReneWerner87
Copy link
Member Author

Ok pls, with target to this branch

@ReneWerner87
Copy link
Member Author

@ksw2000 PR would be great

@ksw2000 ksw2000 mentioned this pull request Jun 20, 2025
8 tasks
ReneWerner87 and others added 2 commits June 20, 2025 15:56
* Make custom context setup via NewWithCustomCtx

* Update docs/api/app.md

* fix lint issues

* small optimizations

* perf: modify app.pool

goos: darwin
goarch: arm64
pkg: github.com/gofiber/fiber/v3
cpu: Apple M4
                       │   old.txt   │              new.txt               │
                       │   sec/op    │   sec/op     vs base               │
_Communication_Flow-10   36.26n ± 0%   34.51n ± 0%  -4.83% (p=0.000 n=30)

                       │  old.txt   │            new.txt             │
                       │    B/op    │    B/op     vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

                       │  old.txt   │            new.txt             │
                       │ allocs/op  │ allocs/op   vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

* perf: optimize defaultCtx in app.next

```
goos: darwin
goarch: arm64
pkg: github.com/gofiber/fiber/v3
cpu: Apple M4
                       │   new.txt   │              new4.txt               │
                       │   sec/op    │   sec/op     vs base                │
_Communication_Flow-10   34.51n ± 0%   30.02n ± 0%  -13.01% (p=0.000 n=30)

                       │  new.txt   │            new4.txt            │
                       │    B/op    │    B/op     vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

                       │  new.txt   │            new4.txt            │
                       │ allocs/op  │ allocs/op   vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal
```

* perf: revert nextCustom

```
goos: darwin
goarch: arm64
pkg: github.com/gofiber/fiber/v3
cpu: Apple M4
                       │  head.txt   │            revert-1.txt            │
                       │   sec/op    │   sec/op     vs base               │
_Communication_Flow-10   30.04n ± 0%   28.74n ± 0%  -4.33% (p=0.000 n=30)

                       │  head.txt  │          revert-1.txt          │
                       │    B/op    │    B/op     vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal

                       │  head.txt  │          revert-1.txt          │
                       │ allocs/op  │ allocs/op   vs base            │
_Communication_Flow-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=30) ¹
¹ all samples are equal
```

---------

Co-authored-by: RW <rene@gofiber.io>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
router.go (1)

209-305: Code duplication concern with next method

The nextCustom method duplicates significant logic from the next method, differing mainly in interface method calls vs direct field access. This creates maintenance overhead as both methods need to be updated when routing logic changes.

Consider extracting the common routing logic into a shared function that accepts abstracted access methods. This would reduce duplication while maintaining the performance benefits of separate execution paths:

type routeAccessor interface {
    getMethodInt() int
    getTreePathHash() uint32
    getIndexRoute() int
    // ... other access methods
}

func (app *App) routeMatch(accessor routeAccessor, setters routeSetters) (bool, error) {
    // Common routing logic here
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01c6c91 and b8a0ed0.

📒 Files selected for processing (2)
  • ctx_interface.go (1 hunks)
  • router.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ctx_interface.go
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: gaby
PR: gofiber/fiber#3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: unit (1.24.x, ubuntu-latest)
  • GitHub Check: unit (1.24.x, macos-latest)
  • GitHub Check: unit (1.24.x, windows-latest)
  • GitHub Check: Analyse
  • GitHub Check: repeated
🔇 Additional comments (3)
router.go (3)

109-153: LGTM - Optimized route matching for default context

The direct field access and unsafe string conversions are appropriate performance optimizations for the default context path. The local indexRoute variable management is more efficient than using getters/setters.


307-347: Unified request handler balances flexibility and performance

The type assertion approach (ctx.(*DefaultCtx)) effectively maintains the performance optimization for the common case while supporting custom contexts. The error handling and flash message processing are correctly duplicated for both paths.

The design choice to keep separate next and nextCustom methods addresses the performance concerns mentioned in the PR objectives, where benchmarking showed a 10-nanosecond degradation when unifying the logic completely.


156-207: Verify HTML escaping consistency across error paths

The error message properly escapes the path using html.EscapeString, which is good for security. However, ensure this escaping approach is consistent with other error handling paths in the codebase.

#!/bin/bash
# Description: Check for consistent HTML escaping in error messages across the codebase
# Expected: All error messages containing user input should use html.EscapeString

echo "Checking for error messages with path/URL content:"
rg -A 2 -B 2 "Cannot.*\+" --type go

echo -e "\n\nChecking for html.EscapeString usage:"
rg "html\.EscapeString" --type go

echo -e "\n\nChecking for potential unescaped user input in error messages:"
rg -A 2 -B 2 "NewError.*\+" --type go

@ReneWerner87 ReneWerner87 merged commit ad64f2c into main Jun 23, 2025
13 of 14 checks passed
@github-project-automation github-project-automation bot moved this to Done in v3 Jun 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants