Route matcher inheritance
Review how you can route traffic along certain paths with inheritable matchers.
Overview
Delegated routes inherit matchers from the parent route table. This way, you can route to specific subpaths that share a common element. Review the following examples of how matcher inheritance works.
Multiple matchers in the same table
Multiple matchers can lead to many matching routes, as shown in the following example.
Say that you have two matchers in a parent route table for the www.example.com
host domain: /product-1
and /product-2
.
The delegated child route table also has two matchers: /foo
and /bar
. The /foo
matcher routes requests to the app-1
virtual destination. The /bar
matcher routes requests to the app-2
virtual destination.
The resulting child routes inherit the parent matchers and can match on the following paths:
www.example.com/product-1/foo
served byapp-1
www.example.com/product-2/foo
served byapp-1
www.example.com/product-1/bar
served byapp-2
www.example.com/product-2/bar
served byapp-2
Example YAML configuration files
# Example of matcher inheritance
# Parent table with two matchers
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: parent
namespace: source-apps
spec:
hosts:
- www.example.com
virtualGateways:
- name: istio-ingressgateway
namespace: gloo-mesh-gateways
http:
- name: product-1
# Match requests along the path `www.example.com/product-1`
matchers:
- uri:
prefix: /product-1
# Delegate requests that match this path to child-a
delegate:
routeTables:
- labels:
table: child-a
- name: product-1
# Match requests along the path `www.example.com/product-2`
matchers:
- uri:
prefix: /product-2
# Delegate requests that match this path to child-a
delegate:
routeTables:
- labels:
table: child-a
---
# Child A route table
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-a
namespace: target-apps
labels:
# Matches label in parent route table to for delegation
table: child-a
spec:
http:
# Table routes matching requests to app-1
- name: product-1
matchers:
- uri:
prefix: /foo
ignoreCase: true
forwardTo:
destinations:
- ref:
name: app-1
namespace: target-apps
port:
number: 8080
kind: VIRTUAL_DESTINATION
# Table routes matching requests to app-2
- name: product-1
matchers:
- uri:
prefix: /bar
ignoreCase: true
forwardTo:
destinations:
- ref:
name: app-2
namespace: target-apps
port:
number: 8080
kind: VIRTUAL_DESTINATION
Separate child tables without matchers
As you saw in the previous example, multiple matchers can lead to many matching routes. These resulting routes might not be what you intended.
Say that you wanted only two matching routes, /product-1
served by the app-1
virtual destination and /product-2
served by the app-2
virtual destination.
With matcher inheritance, you can configure your parent and child route tables to achieve this scenario. In the parent route table, specify the full matchers for the resulting routes that you want in the parent route table. Each matcher delegates to a separate child route table. In the child route tables, do not add more matchers. Instead, the child route tables inherit the matchers from the parent. The child route tables specify the apps to route to.
The resulting child routes inherit the parent matchers and can match on the following paths:
www.example.com/product-1
served byapp-1
www.example.com/product-2
served byapp-2
Example YAML configuration files
# Example of matcher inheritance
# Parent table with two matchers
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: parent
namespace: source-apps
spec:
hosts:
- www.example.com
virtualGateways:
- name: istio-ingressgateway
namespace: gloo-mesh-gateways
http:
- name: product-1
# Match requests along the path `www.example.com/product-1`
matchers:
- uri:
prefix: /product-1
ignoreCase: true
# Delegate requests that match this path to child-a
delegate:
routeTables:
- labels:
table: child-a
- name: product-1
# Match requests along the path `www.example.com/product-2`
matchers:
- uri:
prefix: /product-2
ignoreCase: true
# Delegate requests that match this path to child-b
delegate:
routeTables:
- labels:
table: child-b
---
# Child A route table
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-a
namespace: target-apps
labels:
# Matches label in parent route table to for delegation
table: child-a
spec:
http:
# Table routes matching requests to app-1
- name: product-1
forwardTo:
destinations:
- ref:
name: app-1
namespace: target-apps
port:
number: 8080
kind: VIRTUAL_DESTINATION
---
# Child B route table
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-b
namespace: target-apps
labels:
# Matches label in parent route table to for delegation
table: child-b
spec:
http:
# Table routes matching requests to app-2
- name: product-2
forwardTo:
destinations:
- ref:
name: app-2
namespace: target-apps
port:
number: 8080
kind: VIRTUAL_DESTINATION
More matcher inheritance rules
Matcher inheritance rules vary depending on the type of matcher that a delegated route inherits. Review the inheritance rules for the following use cases:
Header Matchers
Child routes inherit header matchers from the parent route. The child route can also set its own header matchers, which are merged with the parent’s header matchers. However, if a child route matches on the same header as the parent, the route is invalid until the conflict is resolved.
Parent example
The following parent route table matches traffic on the one.solo.io
host with the X-delegated=true
header, and delegates requests to child route tables with the table=child
label.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: parent-rt
namespace: global
spec:
hosts:
- 'one.solo.io'
virtualGateways:
- name: istio-ingressgateway
namespace: bookinfo
cluster: ${CLUSTER_NAME}
http:
- matchers:
- headers:
- name: X-delegated
value: true
delegate:
routeTables:
- labels:
table: child
Child with more header matchers example
The following child route table has a matcher for the X-child
header. It inherits the X-delegated
header matcher from the parent. As such, it matches traffic with the X-child=true
and X-delegate=true
headers.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt1
namespace: global
labels:
table: child
spec:
http:
- matchers:
- headers:
- name: X-child
value: true
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Child conflict example
The following child route table also has a matcher for the X-delegated
header. As such, the route is invalid and does not work until you resolve the conflict.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt2
namespace: global
labels:
table: child
spec:
http:
- matchers:
- headers:
- name: X-delegated
value: sometimes
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Inverted header matchers
Child routes inherit inverted header matchers (invertMatch=true
) from the parent route. The child route can also set its own inverted header matchers, which are merged with the parent’s header matchers. However, if a child route matches on the same inverted header as the parent, the route is invalid until the conflict is resolved.
Parent example
The following parent route table matches traffic on the one.solo.io
host with an inverted header matcher for the X-version
header. This inverted matcher means that traffic can only match without the X-version=v1
header. For example, traffic with X-version=v1
is not forwarded. However, traffic with X-version=v2
and so on is matched and delegated to child route tables with the table=child
label.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: parent-rt
namespace: global
spec:
hosts:
- 'one.solo.io'
virtualGateways:
- name: istio-ingressgateway
namespace: bookinfo
cluster: ${CLUSTER_NAME}
http:
- matchers:
- headers:
- name: X-version
value: v1
invertMatch: true
delegate:
routeTables:
- labels:
table: child
Child with more inverted matchers example
The following child route table has an inverted matcher for the X-env=prod
header. It inherits the X-version=v1
inverted header matcher from the parent. As such, it does not match traffic with the X-version=v1
or X-env=prod
headers.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt1
namespace: global
labels:
table: child
spec:
http:
- matchers:
- headers:
- name: X-env
value: prod
invertMatch: true
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Child conflict example
The following child route table also has an inverted matcher for the X-version
header, this time with v2
. Note that the values are not merged together to block matches on both X-version=v1
and X-version=v2
headers. Instead, the route is invalid and does not work until you resolve the conflict.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt2
namespace: global
labels:
table: child
spec:
http:
- matchers:
- headers:
- name: X-version
value: v2
invertMatch: true
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Query parameter matchers
Child routes inherit query parameter matchers from the parent route. The child route can also set its own query parameter matchers, which are merged with the parent’s matchers. However, if a child route matches on the same query parameter as the parent, the route is invalid until the conflict is resolved.
Parent example
The following parent route table matches traffic on the one.solo.io
host with the version=v1
query parameter, and delegates requests to child route tables with the table=child
label.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: parent-rt
namespace: global
spec:
hosts:
- 'one.solo.io'
virtualGateways:
- name: istio-ingressgateway
namespace: bookinfo
cluster: ${CLUSTER_NAME}
http:
- matchers:
- queryParameters:
- name: version
value: v1
delegate:
routeTables:
- labels:
table: child
Child with more query matchers example
The following child route table has a matcher for the env
query parameter. It inherits the version
matcher from the parent. As such, it matches traffic with the ?version=v1
and ?env=staging
query parameters.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt1
namespace: global
labels:
table: child
spec:
http:
- matchers:
- queryParameters:
- name: env
value: staging
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Child conflict example
The following child route table also has a matcher for the version
query parameter, this time with v2
. Note that the values are not merged together to match requests on both ?version=v1
and ?version=v2
queries. Instead, the route is invalid and does not work until you resolve the conflict.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt2
namespace: global
labels:
table: child
spec:
http:
- matchers:
- queryParameter:
- name: version
value: v2
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
HTTP method
Child routes inherit HTTP method matchers from the parent route. The child route cannot set a different HTTP method. If the child has a conflicting HTTP method matcher, the route is invalid until the conflict is resolved.
Parent example
The following parent route table matches PATCH
methods on the one.solo.io
host, and delegates requests to child route tables with the table=child
label.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: parent-rt
namespace: global
spec:
hosts:
- 'one.solo.io'
virtualGateways:
- name: istio-ingressgateway
namespace: bookinfo
cluster: ${CLUSTER_NAME}
http:
- matchers:
- method: PATCH
delegate:
routeTables:
- labels:
table: child
Child inheritance example
The following child route table does not set a matcher. Instead, it inherits the PATCH
method matcher from the parent route table. Requests with the PATCH
method to one.solo.io
are resolved to the myapp
destination that the child route forwards to.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt1
namespace: global
labels:
table: child
spec:
http:
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Child conflict example
The following child route table also matches on a method, PUT
. Because this method conflicts with the parent method, the route is invalid and does not work until you resolve the conflict.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt2
namespace: global
labels:
table: child
spec:
http:
- matchers:
- method: PUT
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Port matcher
Child routes inherit the HTTP port matcher from the parent route, even if the parent does not have a port matcher. The child route cannot have its own HTTP port matcher. If it does, the child route’s port matcher is ignored.
Parent example
The following parent route table matches the 8090
port on the one.solo.io
host, and delegates requests to child route tables with the table=child
label.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: parent-rt
namespace: global
spec:
hosts:
- 'one.solo.io'
virtualGateways:
- name: istio-ingressgateway
namespace: bookinfo
cluster: ${CLUSTER_NAME}
http:
- matchers:
- port: 8090
delegate:
routeTables:
- labels:
table: child
Child inheritance example
The following child route table does not set a port matcher. Instead, it inherits the 8090
port matcher from the parent route table. Requests to one.solo.io:8090
are resolved to the myapp
destination that the child route forwards to.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt1
namespace: global
labels:
table: child
spec:
http:
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE
Child ignored example
The following child route table also matches on a port, 8091
. However, port matchers on a child route are ignored. Requests to one.solo.io:8091
are not resolved along this route. Instead, the child route inherits the parent’s port matcher of 8090
. Requests to one.solo.io:8090
are resolved to the myapp
destination that the child route forwards to.
apiVersion: networking.gloo.solo.io/v2
kind: RouteTable
metadata:
name: child-rt2
namespace: global
labels:
table: child
spec:
http:
- matchers:
- port: 8091
forwardTo:
destinations:
- ref:
name: myapp
namespace: global
cluster: ${CLUSTER_NAME}
port:
number: 8090
kind: SERVICE