Skip to content

GEP: Add support for query parameter in the HTTPRouteFilter API #2895

Closed as not planned
@lianglli

Description

@lianglli

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.

Metadata

Metadata

Assignees

Labels

kind/featureCategorizes issue or PR as related to a new feature.kind/gepPRs related to Gateway Enhancement Proposal(GEP)lifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions