[GH-ISSUE #224] [FEATURE REQUEST] Allow grouping middleware #1097

Closed
opened 2026-03-07 22:05:39 +03:00 by kerem · 6 comments
Owner

Originally created by @bojanz on GitHub (Jan 13, 2021).
Original GitHub issue: https://github.com/hibiken/asynq/issues/224

Originally assigned to: @hibiken on GitHub.

Is your feature request related to a problem? Please describe.
Asynq's processors resemble HTTP handlers, down to the multiplexer. This was a great choice, and makes the API easy to use.

Right now the multiplexer allows adding middleware via mux.Use(), but that middleware is always global. There is no way to declare middleware only for a certain group of tasks. If some tasks process orders and some tasks process products, it gets tricky to have a middleware that loads an order and puts it in the context, and a middleware that loads a product and puts it in the context.

Describe the solution you'd like
My suggestion is to copy the approach that routers like Chi take, and also offer a Group() method.

This would allow code like:

group := mux.Group()
group.Use(productMiddleware)
group.HandleFunc("product:update", handler)

group := mux.Group()
group.Use(orderMiddleware)
group.HandleFunc("order:refund", handler)

This is deep in the "nice to have" territory, just figured it's worth suggesting.

Originally created by @bojanz on GitHub (Jan 13, 2021). Original GitHub issue: https://github.com/hibiken/asynq/issues/224 Originally assigned to: @hibiken on GitHub. **Is your feature request related to a problem? Please describe.** Asynq's processors resemble HTTP handlers, down to the multiplexer. This was a great choice, and makes the API easy to use. Right now the multiplexer allows adding middleware via mux.Use(), but that middleware is always global. There is no way to declare middleware only for a certain group of tasks. If some tasks process orders and some tasks process products, it gets tricky to have a middleware that loads an order and puts it in the context, and a middleware that loads a product and puts it in the context. **Describe the solution you'd like** My suggestion is to copy the approach that routers like Chi take, and also offer a Group() method. This would allow code like: ``` group := mux.Group() group.Use(productMiddleware) group.HandleFunc("product:update", handler) group := mux.Group() group.Use(orderMiddleware) group.HandleFunc("order:refund", handler) ``` This is deep in the "nice to have" territory, just figured it's worth suggesting.
kerem 2026-03-07 22:05:39 +03:00
Author
Owner

@hibiken commented on GitHub (Jan 13, 2021):

@bojanz Thank you for opening this issue! (Your questions and suggestions are always spot-on!)

I personally have not used chi but this API is definitely nice to have. Especially as your Handler grows, this grouping of task handlers is going to be very helpful.

Let's implement this feature. Feel free to create a PR if you are interested in implementing 👍

<!-- gh-comment-id:759828428 --> @hibiken commented on GitHub (Jan 13, 2021): @bojanz Thank you for opening this issue! (Your questions and suggestions are always spot-on!) I personally have not used `chi` but this API is definitely nice to have. Especially as your Handler grows, this grouping of task handlers is going to be very helpful. Let's implement this feature. Feel free to create a PR if you are interested in implementing 👍
Author
Owner

@bojanz commented on GitHub (Jan 13, 2021):

Thanks, I appreciate that.

I can look into this in about a week. If anyone needs it before then, feel free to go around me.

<!-- gh-comment-id:759834102 --> @bojanz commented on GitHub (Jan 13, 2021): Thanks, I appreciate that. I can look into this in about a week. If anyone needs it before then, feel free to go around me.
Author
Owner

@hibiken commented on GitHub (Jan 14, 2021):

Actually I believe you can accomplish this by composing multiple ServeMux . Since ServeMux performs prefix matching, as long as each "group" has the same type prefix, you can group them.

Example:

productHandlers := asynq.NewServeMux()
productHandlers.Use(productMiddleware)
productHandlers.HandleFunc("product:update", productUpdateTaskHandler)

orderHandlers := asynq.NewServeMux()
orderHandler.Use(orderMiddleware)
orderHandlers.HandleFunc("order:refund", orderRefundTaskHandler)

// Top level handler
mux := asynq.NewServeMux()
mux.Use(someGlobalMiddleware)
mux.Handle("product:", productHandlers)
mux.Handle("order:", orderHandlers)

Let me know if this solution works!

<!-- gh-comment-id:760441918 --> @hibiken commented on GitHub (Jan 14, 2021): Actually I believe you can accomplish this by composing multiple `ServeMux` . Since `ServeMux` performs prefix matching, as long as each "group" has the same type prefix, you can group them. Example: ```go productHandlers := asynq.NewServeMux() productHandlers.Use(productMiddleware) productHandlers.HandleFunc("product:update", productUpdateTaskHandler) orderHandlers := asynq.NewServeMux() orderHandler.Use(orderMiddleware) orderHandlers.HandleFunc("order:refund", orderRefundTaskHandler) // Top level handler mux := asynq.NewServeMux() mux.Use(someGlobalMiddleware) mux.Handle("product:", productHandlers) mux.Handle("order:", orderHandlers) ``` Let me know if this solution works!
Author
Owner

@bojanz commented on GitHub (Jan 19, 2021):

That works wonderfully, updated my code to do that instead of checking the task type in middleware. Thank you!

I guess all we need is a bit of docs in the wiki for this, then?

<!-- gh-comment-id:762862269 --> @bojanz commented on GitHub (Jan 19, 2021): That works wonderfully, updated my code to do that instead of checking the task type in middleware. Thank you! I guess all we need is a bit of docs in the wiki for this, then?
Author
Owner

@hibiken commented on GitHub (Jan 19, 2021):

Awesome! I'll keep this issue open as a reminder to update the wiki 👍

<!-- gh-comment-id:762894635 --> @hibiken commented on GitHub (Jan 19, 2021): Awesome! I'll keep this issue open as a reminder to update the wiki 👍
Author
Owner

@hibiken commented on GitHub (Apr 13, 2021):

Done! See the documentation here.

<!-- gh-comment-id:818755957 --> @hibiken commented on GitHub (Apr 13, 2021): Done! See the documentation [here](https://github.com/hibiken/asynq/wiki/Handler-Deep-Dive#grouping-middlewares).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/asynq#1097
No description provided.