Thanks to visit codestin.com
Credit goes to github.com

Skip to content

🔥 feat: Add response time middleware#3891

Merged
ReneWerner87 merged 2 commits intomainfrom
implement-response-time-middleware
Nov 24, 2025
Merged

🔥 feat: Add response time middleware#3891
ReneWerner87 merged 2 commits intomainfrom
implement-response-time-middleware

Conversation

@gaby
Copy link
Member

@gaby gaby commented Nov 23, 2025

Summary

  • add configurable response time middleware and response header constant
  • cover middleware with table-driven tests for header formatting, skip logic, and error propagation

Based on: https://expressjs.com/en/resources/middleware/response-time.html

@gaby gaby requested a review from a team as a code owner November 23, 2025 06:48
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 23, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a ResponseTime middleware that measures per-request handling duration and writes it to a configurable response header. Introduces configuration, implementation, tests, a new exported header constant, and documentation.

Changes

Cohort / File(s) Summary
Documentation
\.github/README.md, docs/middleware/responsetime.md, docs/whats_new.md
Adds public-facing entry and full docs for ResponseTime middleware, including API (New(config ...Config)), examples, default header, and Next skip-hook details.
Constants
constants.go
Adds exported constant HeaderXResponseTime = "X-Response-Time".
Middleware — Config
middleware/responsetime/config.go
Introduces Config struct (Next func(c fiber.Ctx) bool, Header string), ConfigDefault, and configDefault(...) helper that applies defaults.
Middleware — Implementation
middleware/responsetime/responsetime.go
Adds New(config ...Config) fiber.Handler middleware: records start time, optionally skips via Next, calls c.Next(), and sets configured header with elapsed duration.
Tests
middleware/responsetime/responsetime_test.go
Adds tests for header emission, skip behavior when Next returns true, and error propagation with custom error handler; parses header as duration.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant Middleware as ResponseTime
    participant App as App Handler (c.Next)

    Client->>Middleware: HTTP Request
    note right of Middleware `#DDEBF7`: record start = now
    Middleware->>Middleware: if cfg.Next(c) == true?
    alt skipped
        Middleware->>App: call c.Next() (skipped timing)
        App-->>Middleware: Response
        Middleware-->>Client: Response (no header)
    else timed
        Middleware->>App: call c.Next()
        App-->>Middleware: Response / error
        note right of Middleware `#F7F6DD`: elapsed = now - start\nset header cfg.Header = elapsed.String()
        Middleware-->>Client: Response with header
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review points:
    • configDefault behavior and defaulting logic in middleware/responsetime/config.go
    • Correct timing boundaries and error propagation in responsetime.go
    • Use and exposure of the new exported constant in constants.go
    • Test assertions parsing header as duration and behavior when Next short-circuits

Suggested reviewers

  • sixcolors
  • ReneWerner87
  • efectn

Poem

🐰 I hopped through code with stopwatch in paw,
I timed each route, exact to the straw,
I tuck the result in a header so neat,
A tiny time ribbon for every request we meet,
Hop on, this middleware makes latency sweet.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description is vague and minimal, lacking details on the changes introduced, documentation updates, testing coverage, and missing most required template sections. Expand the description to include: details on configuration options (Next, Header fields), links to documentation files added, confirmation of test coverage specifics, and explicit checklist confirmations per the template.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main feature being added: response time middleware, which aligns with the substantial changes across the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch implement-response-time-middleware

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 467c0d3 and ffddf72.

📒 Files selected for processing (3)
  • docs/middleware/responsetime.md (1 hunks)
  • docs/whats_new.md (1 hunks)
  • middleware/responsetime/responsetime.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • middleware/responsetime/responsetime.go
  • docs/whats_new.md
  • docs/middleware/responsetime.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: lint
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: Compare
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: repeated

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gaby, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates a new responsetime middleware into the Fiber framework. Its primary function is to automatically calculate the processing duration of each incoming request and append this timing information to the response headers. This feature provides developers with an immediate, per-request performance metric, enhancing observability. The middleware is highly configurable, allowing users to specify a custom header name or disable the header entirely, and includes a Next function for fine-grained control over which requests are processed, such as skipping health checks.

Highlights

  • New responsetime Middleware: Introduced a new middleware to measure and expose request handling duration.
  • Configurable Response Header: The middleware writes the duration to a configurable HTTP response header, defaulting to "X-Response-Time".
  • Skip Logic: Includes a Next function in the configuration to conditionally skip the middleware for specific requests.
  • Comprehensive Testing: Implemented table-driven tests covering header formatting, skip logic, and error propagation.
  • Documentation: Added detailed documentation for the new middleware, including usage examples and configuration.
  • Code Quality Improvements: Addressed linting feedback by grouping imports and removing redundant loop copies within the middleware.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ReneWerner87 ReneWerner87 added this to v3 Nov 23, 2025
@ReneWerner87 ReneWerner87 added this to the v3 milestone Nov 23, 2025
@gaby gaby changed the title Add response time middleware and documentation 🔥 feat: Add response time middleware Nov 23, 2025
@codecov
Copy link

codecov bot commented Nov 23, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.73%. Comparing base (73929b0) to head (ffddf72).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3891      +/-   ##
==========================================
+ Coverage   91.70%   91.73%   +0.03%     
==========================================
  Files         115      117       +2     
  Lines        9981     9997      +16     
==========================================
+ Hits         9153     9171      +18     
+ Misses        528      527       -1     
+ Partials      300      299       -1     
Flag Coverage Δ
unittests 91.73% <100.00%> (+0.03%) ⬆️

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.

Copy link
Contributor

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 response time middleware for Fiber that measures request processing duration and exposes it via a configurable response header. The implementation follows the established Fiber middleware patterns with proper configuration support and includes comprehensive documentation.

Key Changes

  • Added response time middleware with configurable header name and skip logic
  • Implemented table-driven tests covering header formatting, skip logic, and error propagation
  • Added HeaderXResponseTime constant to the Fiber constants collection

Reviewed changes

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

Show a summary per file
File Description
middleware/responsetime/responsetime.go Core middleware implementation that measures elapsed time using time.Now() and time.Since()
middleware/responsetime/config.go Configuration structure with Next and Header options, following standard Fiber middleware patterns
middleware/responsetime/responsetime_test.go Table-driven tests for default behavior, skip logic, and error propagation
middleware/responsetime/config.go Config defaults and helper function for applying default values
constants.go Added HeaderXResponseTime constant in alphabetical order
docs/middleware/responsetime.md Complete documentation with examples for default, custom header, and skip configurations
docs/whats_new.md What's new entry describing the middleware functionality
.github/README.md Added middleware to the list with description

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new responsetime middleware, which is a valuable addition to Fiber's middleware collection. The implementation is clean, and it comes with comprehensive documentation and a good set of initial tests.

My review has identified one high-severity issue where the documented feature to disable the response header via an empty string is not functional due to the default configuration logic. I've also suggested an improvement to the test suite to cover custom header names, enhancing its completeness.

Overall, this is a solid contribution that will be even better once these points are addressed.

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)
middleware/responsetime/responsetime_test.go (1)

14-99: Well-structured test coverage.

The tests are comprehensive and follow good practices:

  • Table-driven design
  • Proper use of t.Parallel()
  • Covers success, skip, and error paths
  • Validates header format by parsing as duration

Optional enhancement: Once the config defaulting issue is resolved, consider adding a test case for explicitly disabling the header:

{
    name:           "disables header when explicitly set to empty",
    expectedStatus: fiber.StatusOK,
    expectHeader:   false,
    explicitEmpty:  true, // new flag
},

Then in the test body:

configs := []Config(nil)
if tt.skipWithNext {
    configs = []Config{{
        Next: func(fiber.Ctx) bool {
            return true
        },
    }}
} else if tt.explicitEmpty {
    configs = []Config{{
        Header: "",
    }}
}

This would explicitly test that users can opt out of the header.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5caa478 and 467c0d3.

📒 Files selected for processing (7)
  • .github/README.md (1 hunks)
  • constants.go (1 hunks)
  • docs/middleware/responsetime.md (1 hunks)
  • docs/whats_new.md (1 hunks)
  • middleware/responsetime/config.go (1 hunks)
  • middleware/responsetime/responsetime.go (1 hunks)
  • middleware/responsetime/responsetime_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:15:26.529Z
Learning: In Fiber v3, net/http handlers (http.Handler, http.HandlerFunc, or raw func(http.ResponseWriter, *http.Request)) can be passed directly to routing methods like app.Get(), app.Post(), etc. The framework automatically detects and wraps them internally via toFiberHandler/collectHandlers. The github.com/gofiber/fiber/v3/middleware/adaptor package is legacy and should not be suggested for tests or code using native net/http handler support.
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/csrf/csrf_test.go:188-193
Timestamp: 2024-09-25T15:57:10.221Z
Learning: In the Fiber framework tests, using `ctx.Response.Header.Cookie` may not be suitable for parsing cookies from the response header, as it requires a `*Cookie` and fills it rather than returning a string value; thus, manual parsing of the `Set-Cookie` header may be necessary.
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/csrf/csrf_test.go:188-193
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In the Fiber framework tests, using `ctx.Response.Header.Cookie` may not be suitable for parsing cookies from the response header, as it requires a `*Cookie` and fills it rather than returning a string value; thus, manual parsing of the `Set-Cookie` header may be necessary.
📚 Learning: 2024-09-25T15:57:10.221Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/csrf/csrf_test.go:188-193
Timestamp: 2024-09-25T15:57:10.221Z
Learning: In the Fiber framework tests, using `ctx.Response.Header.Cookie` may not be suitable for parsing cookies from the response header, as it requires a `*Cookie` and fills it rather than returning a string value; thus, manual parsing of the `Set-Cookie` header may be necessary.

Applied to files:

  • constants.go
  • middleware/responsetime/responsetime_test.go
📚 Learning: 2025-10-16T07:15:26.529Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:15:26.529Z
Learning: In Fiber v3, net/http handlers (http.Handler, http.HandlerFunc, or raw func(http.ResponseWriter, *http.Request)) can be passed directly to routing methods like app.Get(), app.Post(), etc. The framework automatically detects and wraps them internally via toFiberHandler/collectHandlers. The github.com/gofiber/fiber/v3/middleware/adaptor package is legacy and should not be suggested for tests or code using native net/http handler support.

Applied to files:

  • .github/README.md
📚 Learning: 2024-09-25T16:17:00.969Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/session/config.go:16-26
Timestamp: 2024-09-25T16:17:00.969Z
Learning: In the session middleware `Config` struct, `Store` is backed by `fiber.Storage`; they are different entities serving distinct purposes in session management.

Applied to files:

  • .github/README.md
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • .github/README.md
  • middleware/responsetime/responsetime.go
📚 Learning: 2024-06-30T00:38:06.580Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3051
File: middleware/session/session.go:215-216
Timestamp: 2024-06-30T00:38:06.580Z
Learning: Parallel tests for `Session.Save` already exist in the `middleware/session/session_test.go` file, specifically in the `Test_Session_Save` and `Test_Session_Save_Expiration` functions.

Applied to files:

  • middleware/responsetime/responsetime_test.go
📚 Learning: 2025-10-16T07:19:52.418Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:19:52.418Z
Learning: In the Fiber codebase, the linter does not allow `require` assertions from within HTTP handlers (including net/http-style handlers). Use `t.Fatalf`, `t.Errorf`, or similar `testing.T` methods for error handling inside handler functions instead.

Applied to files:

  • middleware/responsetime/responsetime_test.go
📚 Learning: 2024-10-12T10:01:44.206Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/session/middleware_test.go:190-191
Timestamp: 2024-10-12T10:01:44.206Z
Learning: When testing session `IdleTimeout` expiration, it's acceptable to use `time.Sleep` to simulate the passage of time in tests.

Applied to files:

  • middleware/responsetime/responsetime_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/responsetime/responsetime_test.go
🧬 Code graph analysis (3)
middleware/responsetime/config.go (1)
constants.go (1)
  • HeaderXResponseTime (283-283)
middleware/responsetime/responsetime_test.go (4)
middleware/responsetime/responsetime.go (1)
  • New (10-31)
constants.go (4)
  • StatusOK (52-52)
  • StatusTeapot (91-91)
  • MethodGet (5-5)
  • HeaderXResponseTime (283-283)
middleware/responsetime/config.go (1)
  • Config (8-18)
app.go (1)
  • ErrorHandler (59-59)
middleware/responsetime/responsetime.go (2)
middleware/responsetime/config.go (1)
  • Config (8-18)
ctx_interface_gen.go (1)
  • Ctx (18-432)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Agent
  • GitHub Check: lint
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: repeated
  • GitHub Check: Compare
🔇 Additional comments (5)
.github/README.md (1)

757-757: LGTM!

The middleware table entry is well-formatted and accurately describes the new responsetime middleware functionality.

constants.go (1)

283-283: LGTM!

The new header constant follows the existing naming conventions and is properly placed within the HTTP Headers section.

docs/middleware/responsetime.md (1)

1-55: Documentation looks good overall.

The documentation is comprehensive and follows Fiber's conventions. However, please verify that line 55's claim about disabling the header by leaving it empty is consistent with the actual implementation (see my comment on config.go).

docs/whats_new.md (1)

1247-1252: Documentation is clear and well-written.

The description accurately explains the middleware's purpose and configuration. However, please ensure the claim about disabling headers by setting Header to an empty string is consistent with the implementation (see my comment on config.go).

middleware/responsetime/responsetime.go (1)

9-31: Implementation logic is correct.

The middleware correctly:

  • Skips execution when Next returns true
  • Measures elapsed time around c.Next()
  • Only sets the header when cfg.Header is non-empty
  • Properly propagates errors from downstream handlers

The logic to allow disabling the header (line 25) is correct, but the config defaulting bug in config.go prevents users from actually setting an empty header. Once that's fixed, this implementation will work as intended.

@ReneWerner87 ReneWerner87 merged commit 4e98910 into main Nov 24, 2025
15 of 16 checks passed
@ReneWerner87 ReneWerner87 deleted the implement-response-time-middleware branch November 24, 2025 08:06
@github-project-automation github-project-automation bot moved this to Done in v3 Nov 24, 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.

3 participants