Description
I'm trying to use gin to build a k8s restapi service,but it seems that there is something wrong with gin’s routing function.
Details
I have defined the following two routes to handle namespaced resource requests and none-namespaced resource requests respectively.
namespacedRouter := router.Group("/:api-version/namespaces")
{
// /{api-version}/namespaces/{namespace-name}/{resource-kind}
namespacedRouter.GET("/:namespace-name/:resource-kind", ApiNamespacedList)
// /{api-version}//namespaces/{namespace-name}/{resource-kind}/{resource-name}
namespacedRouter.GET("/:namespace-name/:resource-kind/:resource-name", ApiNamespacedGet)
}
naneNamespacedRouter := router.Group("/:api-version")
{
// /{api-version}/{resource-kind}
naneNamespacedRouter.GET("/:resource-kind", ApiNoneNamespacedList)
// /{api-version}/{resource-kind}/{resource-name}
naneNamespacedRouter.GET("/:resource-kind/:resource-name", ApiNoneNamespacedGet)
}
These routes work fine for namespaced resources, but only partially match none-namespaced resources.
Like this:
namespaced-list ok api/v1/namespaces/kube-system/pods
namespaced-get ok api/v1/namespaces/kube-system/pods/etcd-minikube
none-namespaced-list ok api/v1/namespaces api/v1/nodes
none-namespaced-get 404 api/v1/namespaces/default
none-namespaced-get ok api/v1/nodes/minikube
In summary, it fails to correctly match the get case for none-namespaced resources named namespaces
My guess is that the namespaces in the path make gin confused and unable to work properly.
Environment
- go version: golang 1.20
- gin version (or commit ref): v1.9.1
- operating system: macOS 13.4 (22F66)
Comment From: arturiamu
After testing, I found that I only need to change api/v1/namespaces/default
to api/v1/ns/default
for normal access.But this result is obviously not what I want, so I hope to understand whether this is a bug in gin logic, or if there is any way for me to use this route normally without using the above method.
Comment From: arturiamu
So it should be certain that there is a problem with gin in the process of processing namespace.
Comment From: f-pisani
Gin does not implement its own router; it uses httprouter as a router. Here's how it works: https://github.com/julienschmidt/httprouter#how-does-it-work.
"/v1/namespaces/default" does not match the "/:api-version/:resource-kind/:resource-name" route because with httprouter, by design, a request can only match exactly one or no route. If you follow the routing path, "/v1/namespaces" matches with "/:api-version/namespaces," and the wildcard path "/:api-version/:resource-kind" is ignored in this case because it can't be "/namespaces" or "/:resource-kind".
You can use another prefix to disambiguate, like "/:api-version/resources/:resource-kind/:resource-name."