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

Inconsistent Middleware Application Based on Route Registration Order #4111

Open
jiaopengzi opened this issue Dec 2, 2024 · 2 comments
Open

Comments

@jiaopengzi
Copy link

jiaopengzi commented Dec 2, 2024

  • With issues:
    Inconsistent Middleware Application Based on Route Registration Order

Description

  • Question 1: Method 1 and Method 2 only differ by the order of registration;Why do Method 1 and Method 2 produce different results? Are these methods legal? Or is this a bug?
  • Question 2: Isn't Method 3 a bit redundant since the same route group is written twice?

How to reproduce

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

type registerFunc func(*gin.RouterGroup) // Type for route registration functions

var registerFuncSlice []registerFunc // Slice of all route registration functions

func init() {
	// Register routes
	registerFuncSlice = append(registerFuncSlice, fooRoutes)
}

func fooHandler(c *gin.Context) {
	key := c.GetString("testKey")
	c.JSON(http.StatusOK, gin.H{"testValue": key})
	c.Abort()
}

func testMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Set("testKey", "test")
		c.Next()
	}
}

func fooRoutes(v1 *gin.RouterGroup) {

	// Method 1: If fooPrivateRoutes is placed before fooPublicRoutes, fooPublicRoutes
	// will apply the testMiddleware (not expected)
	// Accessing http://127.0.0.1:8888/v1/test/no-test-data returns {"testValue":"test"}
	foo := v1.Group("/test")
	fooPrivateRoutes(foo)
	fooPublicRoutes(foo)

	//// Method 2: If fooPrivateRoutes is placed after fooPublicRoutes, fooPublicRoutes
	//// will not apply the testMiddleware (expected)
	//// Accessing http://127.0.0.1:8888/v1/test/no-test-data returns {"testValue":""}
	//foo := v1.Group("/test")
	//fooPublicRoutes(foo)
	//fooPrivateRoutes(foo)

	//// Method 3: Separate the two, regardless of the order (expected)
	//// Accessing http://127.0.0.1:8888/v1/test/no-test-data returns {"testValue":""}
	//fooPrivate := v1.Group("/test")
	//fooPrivateRoutes(fooPrivate)
	//
	//fooPublic := v1.Group("/test")
	//fooPublicRoutes(fooPublic)

	/*
		Question 1: Method 1 and Method 2 only differ by the order of registration;
		Why do Method 1 and Method 2 produce different results? Are these methods legal? Or is this a bug?

		Question 2: Isn't Method 3 a bit redundant since the same route group is written twice?
	*/
}

func fooPublicRoutes(group *gin.RouterGroup) {
	group.GET("/no-test-data", fooHandler)
}

func fooPrivateRoutes(group *gin.RouterGroup) {
	test := group.Use(testMiddleware())
	test.GET("/has-test-data", fooHandler)
}

func setupRouter() *gin.Engine {
	e := gin.Default()
	v1 := e.Group("v1") // Register route group

	// Dynamically register all routes
	for _, regFunc := range registerFuncSlice {
		regFunc(v1)
	}

	if err := e.Run("127.0.0.1:8888"); err != nil {
		panic(err)
	}
	return e
}

func main() {
	setupRouter()
}

Expectations

$ curl http://127.0.0.1:8888/v1/test/no-test-data
{"testValue":""}

Actual result

$ curl http://127.0.0.1:8888/v1/test/no-test-data
{"testValue":"test"}

Environment

  • go version:go1.23.3
  • gin version:v1.10.0
  • operating system:windows 11
@simon-winter
Copy link

related: #4109

@jiaopengzi
Copy link
Author

hello @manucorporat

  1. Why do I need to pay attention to the registration order within the same route group for Method 1 and Method 2? I find this unreasonable.
  2. Why does Method 3 work when written separately, even though it belongs to the same route group?

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

No branches or pull requests

2 participants