Skip to content

Feature Request: Optional trailing slash handling (without redirect) #4411

@RezaKargar

Description

@RezaKargar

Feature Description

Summary

Add an optional router configuration that allows Gin to treat routes with and without a trailing slash as equivalent, without performing a redirect.

When this option is enabled, routes like /health and /health/ should both be handled by the same route handler, even if only one of them was explicitly registered.

Motivation

Currently, Gin uses redirection to normalize trailing slashes.
If a route /health is registered, a request to /health/ results in a 301 or 307 redirect (depending on the request method).
While this behavior is correct for many web applications, it can be undesirable in APIs and microservices, where:

  • Redirects introduce unnecessary latency.
  • Some clients don’t expect or handle redirects well.
  • Users want a consistent experience where /foo and /foo/ are logically the same endpoint.

This feature would make Gin more flexible and better suited for these use cases.

Proposal

Introduce a new Engine (or RouterGroup) option to enable this behavior, for example:

r := gin.New()
r.SetTrailingSlashBehavior(gin.TrailingSlashIgnore)

or via a configuration flag:

r := gin.Default()
r.IgnoreTrailingSlash = true

When enabled:

  • /health and /health/ both match the same route, without redirecting.
  • Registered paths in the router tree should match regardless of the trailing slash.
  • The original Request.URL.Path should remain unchanged.

Example

r := gin.Default()
r.IgnoreTrailingSlash = true

r.GET("/health", func(c *gin.Context) {
    c.String(200, "ok")
})

r.Run()

Expected behavior:

Request Response Redirect
GET /health 200 OK
GET /health/ 200 OK

Alternatives Considered

  • RedirectTrailingSlash(false) disables redirects but results in 404 for the alternate path.
  • Manually registering both /path and /path/.
  • Middleware to normalize paths.

Implementation Notes

This feature would require a small change in the router tree’s lookup logic (tree.go, node.go), particularly in:

  • findRoute
  • getValue
  • findCaseInsensitivePath

The idea is to optionally ignore the trailing slash difference when matching static nodes, for example:

if len(path) == len(prefix)-1 && prefix[len(prefix)-1] == '/' {
    if e.ignoreTrailingSlash {
        return matchedHandler
    }
}

References

  • Related Gin issues: #388, #2415
  • Similar feature in Echo: Echo#TrailingSlashRedirect

Benefit

This feature provides flexibility, avoids unwanted redirects, and improves developer experience for APIs that treat /path and /path/ equally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/proposalGot an idea for a feature that Gin doesn't have currently? Submit your idea here!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions