title: ApisixRoute

ApisixRoute is a CRD resource which focus on how to route traffic to expected backend, it exposes many features supported by Apache APISIX. Compared to Ingress, functions are implemented in a more native way, with stronger semantics.

Path based route rules

URI path are always used to split traffic, for instance, requests with host foo.com and /foo prefix should be routed to service foo while requests which path is /bar should be routed to service bar, in the manner of ApisixRoute, the configuration should be:

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: foo-bar-route
spec:
  http:
  - name: foo
    match:
      hosts:
      - foo.com
      paths:
      - "/foo*"
    backend:
     serviceName: foo
     servicePort: 80
  - name: bar
    match:
      paths:
        - "/bar"
    backend:
      serviceName: bar
      servicePort: 80

There are two path types can be used, prefix and exact, default is exact, while if prefix is desired, just append a *, for instance, /id/* matches all paths with the prefix of /id/.

Advanced route features

Path based route are most common, but if it's not enough, try other route features in ApisixRoute such as methods, exprs.

The methods splits traffic according to the HTTP method, the following configurations routes requests with GET method to foo service (a Kubernetes Service).

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: method-route
spec:
  http:
    - name: method
      match:
        paths:
        - /
        methods:
        - GET
      backends:
        - serviceName: foo
          servicePort: 80

The exprs allows user to configure match conditions with arbitrary predicates in HTTP, such as queries, HTTP headers, Cookie. It's composed by several expressions, which in turn composed by subject, operator and value/set.

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: method-route
spec:
  http:
    - name: method
      match:
        paths:
          - /
        exprs:
          - subject:
              scope: Query
              name: id
            op: Equal
            value: 2143
      backends:
        - serviceName: foo
          servicePort: 80

The above configuration configures an extra route match condition, which asks the query id must be equal to 2143.

Service Resolution Granularity

By default a referenced Service will be watched, so it‘s newest endpoints list can be updated to Apache APISIX. apisix-ingress-controller provides another mechanism that just use the ClusterIP of this service, if that’s what you want, just set the resolveGranularity to service (default is endpoint).

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: method-route
spec:
  http:
    - name: method
      match:
        paths:
          - /*
        methods:
          - GET
      backends:
        - serviceName: foo
          servicePort: 80
          resolveGranularity: service

Weight Based Traffic Split

There can more than one backend specified in one route rule, when multiple backends co-exist there, the traffic split based on weights will be applied (which actually uses the traffic-split plugin in Apache APISIX). You can specify weight for each backend, the default weight is 100.

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: method-route
spec:
  http:
    - name: method
      match:
        paths:
          - /*
        methods:
          - GET
        exprs:
          - subject:
              scope: Header
              name: User-Agent
            op: RegexMatch
            value: ".*Chrome.*"
      backends:
        - serviceName: foo
          servicePort: 80
          weight: 100
        - serviceName: bar
          servicePort: 81
          weight: 50

The above ApisixRoute has one route rule, which contains two backends foo and bar, the weight ratio is 100:50, which means 2/3 requests (with GET method and User-Agent matching regex pattern .*Chrome.*) will be sent to service foo and 1/3 requests will be proxied to serivce bar.

Plugins

Apache APISIX provides more than 40 plugins, which can be used in ApisixRoute. All configuration items are named same to the one in APISIX.

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: httpbin-route
spec:
  http:
    - name: httpbin
      match:
        hosts:
        - local.httpbin.org
        paths:
          - /*
      backends:
        - serviceName: foo
          servicePort: 80
      plugins:
        - name: cors
          enable: true

The above configuration enables Cors plugin for requests which host is local.httpbin.org.

Websocket Proxy

Websocket service can be proxied by creating a route with specifying the websocket field.

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: ws-route
spec:
  http:
    - name: websocket
      match:
        hosts:
          - ws.foo.org
        paths:
          - /*
      backends:
        - serviceName: websocket-server
          servicePort: 8080
      websocket: true

TCP Route

apisix-ingress-controller supports the port-based tcp route.

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: tcp-route
spec:
  stream:
    - name: tcp-route-rule1
      protocol: TCP
      match:
        ingressPort: 9100
      backend:
        serviceName: tcp-server
        servicePort: 8080

The above yaml configuration guides TCP traffic entered to the Ingress proxy server (i.e. APISIX) port 9100 should be routed to the backend service tcp-server.

Note since APISIX doesn't support dynamic listening, so here the 9100 port should be pre-defined in APISIX configuration.

UDP Route

apisix-ingress-controller supports the port-based udp route.

apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
  name: udp-route
spec:
  stream:
    - name: udp-route-rule1
      protocol: UDP
      match:
        ingressPort: 9200
      backend:
        serviceName: udp-server
        servicePort: 53

The above yaml configuration guides UDP traffic entered to the Ingress proxy server (i.e. APISIX) port 9200 should be routed to the backend service udp-server.

Note since APISIX doesn't support dynamic listening, so here the 9200 port should be pre-defined in APISIX configuration.