Description
What would you like to be added:
It would be great if HTTPRouteFilter had a field to set, add and remove a query parameter of the HTTP request before it is sent to the upstream target.
This can be done by adding a new field QueryParamModifier of type HTTPRouteFilter.
The QueryParamModifier is extended.
// HTTPRouteFilterType identifies a type of HTTPRoute filter.
type HTTPRouteFilterType string
const (
// HTTPRouteFilterQueryParamModifier can be used to set, add or remove an query
// parameter from an HTTP request before it is sent to the upstream target.
//
// Support in HTTPRouteRule: Core
//
// Support in HTTPBackendRef: Extended
HTTPRouteFilterQueryParamModifier HTTPRouteFilterType = "QueryParamModifier"
)
// HTTPQueryParamFilter defines a filter that modifies HTTP query parameter.
// Only one action for a given query param name is permitted.
// Filters specifying multiple actions of the same or different type for any one
// query param name are invalid and will be rejected by CRD validation.
type HTTPQueryParamFilter struct {
// Set overwrites the HTTP request with the given query param (name, value)
// before the action. The request query parameter names are case-sensitive.
// This must be an exact string match of query param name.
// (See https://tools.ietf.org/html/rfc7230#section-2.7.3).
//
// Input:
// GET /foo?my-parameter=foo HTTP/1.1
//
// Config:
// set:
// - name: "my-parameter"
// value: "bar"
//
// Output:
// GET /foo?my-parameter=bar HTTP/1.1
//
//
// +optional
// +listType=map
// +listMapKey=name
// +kubebuilder:validation:MaxItems=16
Set []HTTPHeader `json:"set,omitempty"`
// Add adds the given query param(s) (name, value) to the HTTP request
// before the action.
//
// Input:
// GET /foo?my-parameter=foo HTTP/1.1
//
// Config:
// add:
// - name: "my-parameter"
// value: "bar"
//
// Output:
// GET /foo?my-parameter=foo&my-parameter=bar HTTP/1.1
//
// +optional
// +listType=map
// +listMapKey=name
// +kubebuilder:validation:MaxItems=16
Add []HTTPHeader `json:"add,omitempty"`
// Remove the given query param(s) from the HTTP request before the action.
// The value of Remove is a list of query param names. Note that the query
// param names are case-sensitive (See
// https://tools.ietf.org/html/rfc7230#section-2.7.3).
//
// Input:
// GET /foo?my-parameter1=foo&my-parameter2=bar&my-parameter3=baz HTTP/1.1
//
// Config:
// remove: ["my-parameter1", "my-parameter3"]
//
// Output:
// GET /foo?my-parameter2=bar HTTP/1.1
//
// +optional
// +listType=set
// +kubebuilder:validation:MaxItems=16
Remove []string `json:"remove,omitempty"`
}
There are many plugins of gatway for manipulating query parameter of HTTP request.
For example, query paramter modification plugin for traefik (ref: https://plugins.traefik.io/plugins/628c9f24ffc0cd18356a97bd/query-paramter-modification) and the request transformer plugin for Kong (ref: https://docs.konghq.com/hub/kong-inc/request-transformer/). Moreover, similar specification can be seen in ingress like tengine-ingress (ref: https://tengine.taobao.org/document/ingress_routes.html nginx.ingress.kubernetes.io/canary-request-add-query).
Why this is needed:
Just like set, add and remove header is useful, the same goes for query parameters.
The query parameters are an important part of the request URL.
The developers can use query parameters to filter, sort or customize data of request body. Backend service can enable different function based on the query parameters. Moreover, query parameters are important information about search and track.
Moreover, query parameter, headers and cookies are common techniques used in a canary release.
For example, it allows to add query parameter for only a certain canary backend, which can help in identifying certain users by the backend service. Based on the following http rule, query parameter "passtoken=74224f54c5b553228f1d1d9795e348f3" will be added to the requests be matched against the query parameter "gray=3", then the request will be routed to the canary service "http-route-canary:80".
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-route-query
spec:
hostnames:
- http.route.query.com
- http.route.queries.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: http-gateway
rules:
- backendRefs:
- kind: Service
name: http-route-production
port: 80
matches:
- path:
type: PathPrefix
value: /
- backendRefs:
- kind: Service
name: http-route-canary
port: 80
filters:
- queryParamModifier:
add:
- name: passtoken
value: 74224f54c5b553228f1d1d9795e348f3
type: QueryParamModifier
matches:
- queryParams:
- name: gray
type: Exact
value: 3
If this requires a GEP, I would be like to start working on it.