Skip to content
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

Draft: fix: middleware ordering #102

Merged
merged 2 commits into from
Mar 26, 2024

Conversation

dylanhitt
Copy link
Collaborator

closes #98

Here's the fix. I'll get the tests up soon. Currently need this to get through the work day.

Thanks

@EwenQuim
Copy link
Member

That's weird. We can clearly see here that it makes future uses of Use after

// Your proposition
func Use(s *Server, middlewares ...func(http.Handler) http.Handler) {
	s.middlewares = append(middlewares, s.middlewares...)
}
fuego.Use(cache)
fuego.Use(compress)

equivalent to

s.middlewares = append(cache, s.middlewares...) // [cache]
s.middlewares = append(compress, s.middlewares...) // [compress, cache], not [cache, compress] as wanted

I might need some tests to understand, I'll see this tomorrow or the day after

@dylanhitt
Copy link
Collaborator Author

dylanhitt commented Mar 25, 2024

Right your ordering there makes sense, in terms of when you use Use. However, register loops from the beginning of the slice. So it's in reverse. I think the code I places here isn't fully correct. And it may be simpler to just reverse the registration loop.

func withMiddlewares(controller http.Handler, middlewares ...func(http.Handler) http.Handler) http.Handler {
	for _, middleware := range middlewares {
		controller = middleware(controller)
	}
	return controller
}

I think using numbers would make it clearer

group := fuego.Group(s, "/v1"
fuego.Use(group, 1)
fuego.Use(group, 2)
fuego.Use(group, 3)

My expectation here would 1 executes before 2 and 3. So when this proposed changed we end up with a slice that looks like

[3, 2, 1]

The loop then registers 3 -> 2 -> 1 -> controller which is the equivalent of a line code like this

1middleware(2middleware(3middleware(controller)))

So in this case the above proposition is wrong

group := fuego.Group(s, "/v1"
fuego.Use(group, 1)
fuego.Use(group, 2)
fuego.Use(group, 3)
fuego.Get(group,  /test,  4, 5)
[4, 5, 3, 2, 1]

@EwenQuim
Copy link
Member

Yes exactly ! We'll reverse the loop order of withMiddlewares

@dylanhitt dylanhitt force-pushed the fix/middleware-order branch from 8f2d403 to 55c025c Compare March 25, 2024 19:41
@dylanhitt
Copy link
Collaborator Author

@EwenQuim Here's my proposal for how we should test it. I will of course add more testing around groups and the other possible combinations of adding middleware i.e Group and on routes directly.

Let me know what you think or if you have a better idea or if you like this and have a thought to add another subset of tests somewhere else be my guest.

Thanks. Fun bug.

@dylanhitt dylanhitt force-pushed the fix/middleware-order branch from cc2c220 to d9fc2b5 Compare March 25, 2024 21:43
@@ -88,7 +88,7 @@ func Register[T any, B any, Contexted ctx[B]](s *Server, method string, path str
func register[T any, B any](s *Server, method string, path string, controller http.Handler, middlewares ...func(http.Handler) http.Handler) Route[T, B] {
fullPath := method + " " + s.basePath + path

allMiddlewares := append(middlewares, s.middlewares...)
allMiddlewares := append(s.middlewares, middlewares...)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Turns out this was still needed when adding middlewares at route level.

Copy link
Member

@EwenQuim EwenQuim left a comment

Choose a reason for hiding this comment

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

Thank you for this fix and great tests!

I think a test with Group might be a final touch to this PR

I'll be merging+release this as soon as it is done!


EDIT: done in 0275c91 @dylanhitt

mux_test.go Show resolved Hide resolved
mux_test.go Show resolved Hide resolved
@EwenQuim EwenQuim merged commit 8a4c82c into go-fuego:main Mar 26, 2024
2 checks passed
@dylanhitt
Copy link
Collaborator Author

I always forget headers.Add exists..

1 similar comment
@dylanhitt
Copy link
Collaborator Author

I always forget headers.Add exists..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clarification on Middleware ordering
2 participants