How to Configure Routes using Expressions

Configuring routes using expressions allows for more flexibility and better performance when dealing with complex or large configurations. This how-to guide explains how to switch to the expressions router and how to configure routes with the new expressive domain specific language. Familiar yourself with the Expressions Language Reference before proceeding through the rest of this guide.

Prerequisites

Edit the kong.conf to contain the line router_flavor = expressions and restart Kong Gateway.

Note: After enabling expressions, traditional match fields on the route object (such as paths and methods) remain configurable. You may specify Expressions in the new expression field. However, these cannot be configured simultaneously with traditional match fields. Additionally, a new priority field, used in conjunction with the expression field, allows you to specify the order of evaluation for Expression routes.

Create routes with expressions

To create a new route object using expressions, send a POST request to the services endpoint:

  1. curl --request POST \
  2. --url http://localhost:8001/services/example-service/routes \
  3. --form-string expression='http.path == "/mock"'

In this example, you associated a new route object with the path /mock to the existing service example-service. The Expressions DSL also allows you to create complex router match conditions:

  1. curl --request POST \
  2. --url http://localhost:8001/services/example-service/routes \
  3. --header 'Content-Type: multipart/form-data' \
  4. --form-string 'expression=(http.path == "/mock" || net.protocol == "https")'

Create complex routes with expressions

You can describe complex route objects using operators within a POST request:

  1. curl --request POST \
  2. --url http://localhost:8001/services/example-service/routes \
  3. --header 'Content-Type: multipart/form-data' \
  4. --form-string name=complex_object \
  5. --form-string 'expression=(net.protocol == "http" || net.protocol == "https") &&
  6. (http.method == "GET" || http.method == "POST") &&
  7. (http.host == "example.com" || http.host == "example.test") &&
  8. (http.path ^= "/mock" || http.path ^= "/mocking") &&
  9. http.headers.x_another_header == "example_header" && (http.headers.x_my_header == "example" || http.headers.x_my_header == "example2")'

See the expressions language overview page for common use cases and how to write expressions routes for them.

For a list of all available language features, see the expressions language reference.

Matching fields

The following table describes the available matching fields, as well as their associated type when using an expressions based router.

FieldTypeAvailable in HTTP SubsystemAvailable in Stream SubsystemDescription
net.protocolStringProtocol of the route. Roughly equivalent to the protocols field on the Route entity. Note: Configured protocols on the Route entity are always added to the top level of the generated route but additional constraints can be provided by using the net.prococol field directly inside the expression.
tls.sniStringIf the connection is over TLS, the servername extension from the ClientHello packet.
http.methodStringThe method of the incoming HTTP request. (for example, “GET” or “POST”)
http.hostStringThe Host header of the incoming HTTP request.
http.pathStringThe normalized request path according to rules defined in RFC 3986. This field value does not contain any query parameters that might exist.
http.path.segments.<segment_index>StringA path segment extracted from the incoming (normalized) http.path with zero-based index. For example, for request path “/a/b/c/“ or “/a/b/c”, http.path.segments.1 will return “b”.
http.path.segments.<segment_index><segment_index>StringPath segments extracted from the incoming (normalized) http.path within the given closed interval joined by “/“. Indexes are zero-based. For example, for request path “/a/b/c/“ or “/a/b/c”, http.path.segments.0_1 will return “a/b”.
http.path.segments.lenIntNumber of segments from the incoming (normalized) http.path. For example, for request path “/a/b/c/“ or “/a/b/c”, http.path.segments.len will return 3.
http.headers.<header_name>String[]The value(s) of request header <header_name>. Note: The header name is always normalized to the underscore and lowercase form, so Foo-Bar, Foo_Bar, and fOo-BAr all become values of the http.headers.foo_bar field.
http.queries.<query_parameter_name>String[]The value(s) of query parameter <query_parameter_name>.
net.src.ipIpAddrIP address of the client.
net.src.portIntThe port number used by the client to connect.
net.dst.ipIpAddrListening IP address where Kong Gateway accepts the incoming connection.
net.dst.portIntListening port number where Kong Gateway accepts the incoming connection.

More information