apache / apache/apisix-ingress-controller
bug: HTTPRoute priority ignored
- Dominant language
- Go
- Stars
- 1.1k
- Forks
- 390
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 12
Description
### Current Behavior
I have an incoming HTTP-request which matches both of the following Gateway API HttpRoutes:
```
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
spec:
parentRefs:
- namespace: apisix
name: apisix
rules:
- matches:
- path:
type: PathPrefix
value: /myservice
backendRefs:
- name: myservice
port: 80
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: api-plugin-config
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: html-route
spec:
parentRefs:
- namespace: apisix
name: apisix
rules:
- matches:
- method: GET
path:
type: RegularExpression
value: ^/myservice/.*/ws_html
backendRefs:
- name: myservice
port: 80
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: html-plugin-config
```
Even so the second route (html-route) has a higher priority in the resulting APISIX admin-api routes (due to the "method: GET" restriction), the first route (api-route) always takes precedence. I basically have no way to use the priority field to change which route should be used first, because the priority is not taken into account. Even setting a priority via CRD ApisixRoute or CRD HTTPRoutePolicy has no effect.
The issue is, that api-route results in the admin API in a route with specific uris, while the html-route results in a route with a less specific uri. This makes the priority field never come into play in the APISIX data-plane.
```
{
"service_id": "39186ba5",
"uris": [
"/myservice",
"/myservice/*"
],
"id": "4e3ab1d8",
"name": "mynamespace_api-route_0-0",
"priority": 47429191680,
"labels": {
...
},
"status": 1,
"modifiedIndex": 1788800112427
},
{
"vars": [
[
"uri",
"~~",
"^/myservice/.*/ws_html"
]
],
"name": "mynamespace_html-route_0-0",
"labels": {
...
},
"status": 1,
"modifiedIndex": 1788959573399,
"service_id": "a93412a2",
"uris": [
"/*"
],
"id": "b1ab2f11",
"methods": [
"GET"
],
"priority": 47433385984
}
```
### Expected Behavior
Since Gateway API does not define the priority of RegexExpression path-matches, I would at least want to be able to use the priority field to define the order.
This would be possible if the PrefixPath path-matches would be transformed to APISIX routes in the same way as the RegexExpression path-matches (with uri "/*" and a vars field for matching the prefix). This would then make it necessary for PrefixPath matching rules to include the prefix-length into the priority calculation.
Actually the APISIX Ingress-Controller priority calculation function has a comment which links to the [calculation function of the kong ingress controller](https://github.com/Kong/kubernetes-ingress-controller/blob/57472721319e2c63e56cb8540425257e8e02520f/internal/dataplane/translator/subtranslator/httproute_atc.go#L279-L296) which does exactly this.
Also Kong considers RegexExpression path-matches to always be more important than PrefixPath path-matches, which makes sense, because usually one chooses the easier PrefixPath setup and only in very special cases switches to the more complicated RegexExpression.
### Error Logs
_No response_
### Steps to Reproduce
- Setup two GatewayAPI HTTPRoutes as above which can be matched by the same request uri.
- Confirm the RegexExpression route has the higher priority value in the resulting APISIX routes config. (Checked via the API, e.g. http://localhost:9180/apisix/admin/configs)
- Send a request which matches both routes.
- The request will take the APISIX route which has a lower value in its priority field.
- There is currently no way via Gateway API to make it use the other route, also not by changing the route-priority using ApisixRoute or HTTPRoutePolicy.
### Environment
- APISIX Ingress controller version: apache/apisix-ingress-controller:2.2.0
- Kubernetes cluster version: v1.35.7-gke.1150000
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the two Gateway API HTTPRoutes and inspect the generated APISIX admin API route configuration, especially the priority calculation and URI/vars representation. Compare the controller's priority calculation with the linked Kong implementation; done means overlapping PrefixPath and RegularExpression matches honor the configured priority and requests select the intended route.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100