Advanced Route Matching

Gloo uses a VirtualService CRD to allow users to specify one or more route rules to handle as a group (Virtual Service). This guide will discuss how to configure Gloo to handle various routing scenarios. These are examples of how to use the Route Matcher.

To give you some context, Gloo Virtual Services contain zero or more Route objects. Each Route contains a Matcher, which is the main way that Gloo uses to determine (or match) if a request coming into the Gloo gateway proxy should be acted on, i.e., forwarded to an upstream. This guide will primarily focus on the details of configuring a Matcher.

In most cases, you can use the glooctl create virtualservice --name <your service name> command (doc here) to create this resource initially. For example,

glooctl create virtualservice --name default
kubectl get virtualservices default --namespace gloo-system --output yaml
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  creationTimestamp: "2019-03-26T20:17:40Z"
  generation: 2
  name: default
  namespace: gloo-system
  resourceVersion: "8904"
  selfLink: /apis/gateway.solo.io/v1/namespaces/gloo-system/virtualservices/default
  uid: 34c5ebc9-5004-11e9-a339-62377b03fa19
spec:
  virtualHost:
    domains:
    - '*'
status:
  reported_by: gateway
  state: 1
  subresource_statuses:
    '*v1.Proxy gloo-system gateway-proxy':
      reported_by: gloo
      state: 1

The following are the different aspects of the request that you can match against a route rule. Each aspect is AND with others, i.e., all aspects must test true for the route to match and the specified route action to be taken.

Path Matching

There are three options to do HTTP path matching. You can specify only one of the following three options within any given route matcher spec. Note, routes is an array of gloo.solo.io.Route objects, and each route has one matcher that can contain one of the path matchers: prefix, exact, or regex.

Given the following example virtual service using the prefix matching against /hello path. For this example, any request to /hello, /hello123, or /hello/other/stuff will all match this route rule.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: default
  namespace: gloo-system
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: /hello
      routeAction:
        single:
          upstream:
            name: default-hello-8080
            namespace: gloo-system

To create the above route using glooctl, you can do the following.

glooctl add route \
    --name default \
    --path-prefix /hello \
    --dest-name default-hello-8080

To test you can use glooctl proxy url to get the Gloo gateway base URL, and then add the path.

curl $(glooctl proxy url)/hello

Here’s how you specify request headers that must be present, and have a matching value, to match the given route rule. You can specify zero or more Header Matcher for each route. Each header matcher has three attributes: name, value, and regex.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: default
  namespace: gloo-system
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        headers:
        - name: foo
          regex: false
          value: bar
        prefix: /hello
      routeAction:
        single:
          upstream:
            name: default-hello-8080
            namespace: gloo-system

To create the above route using glooctl, you can do the following. Multiple --headers can be specified. The CLI will try to inspect the provided value to guess if its a regular expression (or not), and set the regex field accordingly.

glooctl add route \
    --name default \
    --header "foo=bar" \
    --path-prefix /hello \
    --dest-name default-hello-8080

To test you can use glooctl proxy url to get the Gloo gateway base URL, and then add the path.

curl --header "foo: bar" $(glooctl proxy url)/hello

Query Parameter

Here’s how you specify request query parameters that must be present, and have a matching value, to match the given route rule. You can specify zero or more Query Parameter Matcher for each route. Each query param matcher has three attributes: name, value, and regex.

For example, the following will match requests who’s path starts with /hello, and has the query parameter ?foo=bar.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: default
  namespace: gloo-system
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        queryParameters:
        - name: foo
          regex: false
          value: bar
        prefix: /hello
      routeAction:
        single:
          upstream:
            name: default-hello-8080
            namespace: gloo-system

To test you can use glooctl proxy url to get the Gloo gateway base URL, and then add the path.

curl "$(glooctl proxy url)/hello?foo=bar"

HTTP Method

You can also create route rules based on the request HTTP method, e.g. GET, POST, DELETE, etc. You can specify one or more HTTP Methods to match against, and if any one of those method verbs is present, the request will match, that is Gloo will conditional OR the match for HTTP Method. Note: since Gloo/Envoy is based on HTTP/2, this gets translated into a header value match against the HTTP/2 :method header, which by spec includes all of the HTTP/1 verbs.

For example, the following will match requests who’s path starts with /hello, and has the HTTP Method GET or POST.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: default
  namespace: gloo-system
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        methods:
        - GET
        - POST
        prefix: /hello
      routeAction:
        single:
          upstream:
            name: default-hello-8080
            namespace: gloo-system

To create the above route using glooctl, you can do the following. Multiple --method options can be specified, and the result matches if any one of the methods is present in the request.

glooctl add route \
    --name default \
    --method GET \
    --method POST \
    --path-prefix /hello \
    --dest-name default-hello-8080

To test you can use glooctl proxy url to get the Gloo gateway base URL, and then add the path.

curl -X GET $(glooctl proxy url)/hello