Skip to main content
Version: 2.5

Router radixtree

what's libradixtree?#

libradixtree, adaptive radix trees implemented in Lua for OpenResty.

APISIX using libradixtree as route dispatching library.

How to use libradixtree in APISIX?#

This is Lua-Openresty implementation library base on FFI for rax.

Let's take a look at a few examples and have an intuitive understanding.

1. Full match#

/blog/foo

It will only match /blog/foo.

2. Prefix matching#

/blog/bar*

It will match the path with the prefix /blog/bar, eg: /blog/bar/a, /blog/bar/b, /blog/bar/c/d/e, /blog/bar etc.

3. Match priority#

Full match -> Deep prefix matching.

Here are the rules:

/blog/foo/*/blog/foo/a/*/blog/foo/c/*/blog/foo/bar
pathMatch result
/blog/foo/bar/blog/foo/bar
/blog/foo/a/b/c/blog/foo/a/*
/blog/foo/c/d/blog/foo/c/*
/blog/foo/gloo/blog/foo/*
/blog/barnot match

4. Parameter match#

When radixtree_uri_with_parameter is used, we can match routes with parameters.

For example, with configuration:

apisix:    router:        http: 'radixtree_uri_with_parameter'

route like

/blog/:name

will match both /blog/dog and /blog/cat.

For more details, see https://github.com/api7/lua-resty-radixtree/#parameters-in-path.

How to filter route by Nginx builtin variable#

Please take a look at radixtree-new, here is an simple example:

$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '{    "uri": "/index.html",    "vars": [        ["http_host", "==", "iresty.com"],        ["cookie_device_id", "==", "a66f0cdc4ba2df8c096f74c9110163a9"],        ["arg_name", "==", "json"],        ["arg_age", ">", "18"],        ["arg_address", "~~", "China.*"]    ],    "upstream": {        "type": "roundrobin",        "nodes": {            "39.97.63.215:80": 1        }    }}'

This route will require the request header host equal iresty.com, request cookie key _device_id equal a66f0cdc4ba2df8c096f74c9110163a9 etc.

How to filter route by graphql attributes#

APISIX supports filtering route by some attributes of graphql. Currently we support:

  • graphql_operation
  • graphql_name
  • graphql_root_fields

For instance, with graphql like this:

query getRepo {    owner {        name    }    repo {        created    }}
  • The graphql_operation is query
  • The graphql_name is getRepo,
  • The graphql_root_fields is ["owner", "repo"]

We can filter such route out with:

$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '{    "methods": ["POST"],    "uri": "/_graphql",    "vars": [        ["graphql_operation", "==", "query"],        ["graphql_name", "==", "getRepo"],        ["graphql_root_fields", "has", "owner"]    ],    "upstream": {        "type": "roundrobin",        "nodes": {            "39.97.63.215:80": 1        }    }}'

To prevent spending too much time reading invalid graphql request body, we only read the first 1 MiB data from the request body. This limitation is configured via:

graphql:  max_size: 1048576

If you need to pass a graphql body which is larger than the limitation, you can increase the value in conf/config.yaml.