Skip to content

feat: [#970] support withoutMiddleware similar to Laravel#1497

Open
u-wlkjyy wants to merge 2 commits into
goravel:masterfrom
u-wlkjyy:feat/without-middleware
Open

feat: [#970] support withoutMiddleware similar to Laravel#1497
u-wlkjyy wants to merge 2 commits into
goravel:masterfrom
u-wlkjyy:feat/without-middleware

Conversation

@u-wlkjyy

Copy link
Copy Markdown

Description

This PR adds support for the WithoutMiddleware method to routes, similar to Laravel's withoutMiddleware() functionality. This allows routes to exclude specific middleware that would otherwise be applied via route groups.

Changes

Framework Contracts

  • Added ExcludedMiddleware field to contracts/http/request.go Info struct
  • Added WithoutMiddleware method to contracts/route/route.go Action interface

Usage Example

facades.Route().Middleware(AuthMiddleware, ThrottleMiddleware).Group(func(router route.Router) {
    // This route has both middlewares
    router.Get("/dashboard", DashboardController.Index)

    // This route excludes ThrottleMiddleware
    router.Get("/api/webhook", WebhookController.Handle).
        WithoutMiddleware(ThrottleMiddleware)
})

Use Cases

  • Webhook endpoints that don't need rate limiting
  • Public API endpoints that bypass authentication from protected groups
  • Specific routes that should skip CSRF protection

Related Issue

Fixes #970

Note

The gin driver implementation will be submitted as a separate PR after this one is merged.

- Add ExcludedMiddleware field to contracts/http.Info
- Add WithoutMiddleware method to contracts/route.Action interface

This allows routes to exclude specific middleware, similar to Laravel's
withoutMiddleware() method. Useful for webhook endpoints, public APIs,
and routes that need to bypass auth/throttling from protected groups.
@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.46%. Comparing base (00f923f) to head (4780e4b).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1497      +/-   ##
==========================================
- Coverage   69.46%   69.46%   -0.01%     
==========================================
  Files         378      378              
  Lines       29723    29726       +3     
==========================================
+ Hits        20648    20649       +1     
- Misses       8123     8124       +1     
- Partials      952      953       +1     

☔ View full report in Codecov by Harness.
📢 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.

@hwbrzzl hwbrzzl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the PR. Please run go tool mockery to generate the latest mock files. And could you implement this style Route::withoutMiddleware([EnsureTokenIsValid::class])->group as well?

Comment thread contracts/http/request.go
Method string `json:"method"`
Name string `json:"name"`
Path string `json:"path"`
ExcludedMiddleware []Middleware `json:"excluded_middleware,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's unnecessary for now, given Middleware doesn't exist as well.

- Add WithoutMiddleware method to Router interface for group-level exclusion
- Regenerate mocks via go tool mockery
- This enables Route.WithoutMiddleware(...).Group(...) style similar to Laravel
@u-wlkjyy

Copy link
Copy Markdown
Author

Thanks for the review! I've addressed both points:

  1. Mock files: Ran go tool mockery to regenerate mocks for the new WithoutMiddleware methods on both Action and Router interfaces (see mocks/route/).

  2. Group-level WithoutMiddleware: Added WithoutMiddleware to the Router interface as well, enabling the Laravel-style usage:

facades.Route().Middleware(authMiddleware).WithoutMiddleware(authMiddleware).Group(func(router route.Router) {
    router.Get("/dashboard", DashboardController.Index)
})

This excludes the middleware for all routes registered within the group. The gin driver implementation is in goravel/gin#229.

@u-wlkjyy

Copy link
Copy Markdown
Author

Note on the test-in-example CI failures: they occur because the example app depends on the released versions of goravel/gin and goravel/fiber, which don't yet implement the new WithoutMiddleware method on Action/Router. This is the expected chicken-and-egg situation when adding a method to a shared interface.

The build errors confirm exactly this:

*Action does not implement route.Action (missing method WithoutMiddleware)
*Group does not implement route.Router (missing method WithoutMiddleware)

This requires coordinated merging:

  1. Framework PR (this one) — adds the interface methods
  2. Driver PRs — goravel/gin#229 (ready), and a corresponding goravel/fiber PR
  3. Tag new driver releases so the example app can pick them up

The gin driver implementation is ready at goravel/gin#229. I can also open a goravel/fiber PR if that helps. Happy to coordinate the merge order however works best.

@hwbrzzl

hwbrzzl commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Note on the test-in-example CI failures: they occur because the example app depends on the released versions of goravel/gin and goravel/fiber, which don't yet implement the new WithoutMiddleware method on Action/Router. This is the expected chicken-and-egg situation when adding a method to a shared interface.

The build errors confirm exactly this:

*Action does not implement route.Action (missing method WithoutMiddleware)
*Group does not implement route.Router (missing method WithoutMiddleware)

This requires coordinated merging:

  1. Framework PR (this one) — adds the interface methods
  2. Driver PRs — goravel/gin#229 (ready), and a corresponding goravel/fiber PR
  3. Tag new driver releases so the example app can pick them up

The gin driver implementation is ready at goravel/gin#229. I can also open a goravel/fiber PR if that helps. Happy to coordinate the merge order however works best.

Yes, it's fine to ignore the test-in-example failure in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants