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 priorityFull match -> Deep prefix matching.
Here are the rules:
/blog/foo/*/blog/foo/a/*/blog/foo/c/*/blog/foo/bar
path | Match 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/bar | not match |
uri
#
4. Different routes have the same When different routes have the same uri
, you can set the priority field of the route to determine which route to match first, or add other matching rules to distinguish different routes.
Note: In the matching rules, the priority
field takes precedence over other rules except uri
.
- Different routes have the same
uri
and set thepriority
field
Create two routes with different priority
values (the larger the value, the higher the priority).
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "upstream": { "nodes": { "127.0.0.1:1980": 1 }, "type": "roundrobin" }, "priority": 3, "uri": "/hello"}'
$ curl http://127.0.0.1:9080/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "upstream": { "nodes": { "127.0.0.1:1981": 1 }, "type": "roundrobin" }, "priority": 2, "uri": "/hello"}'
Test:
curl http://127.0.0.1:1980/hello1980
All requests only hit the route of port 1980
.
- Different routes have the same
uri
and set different matching conditions
Here is an example of setting host matching rules:
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "upstream": { "nodes": { "127.0.0.1:1980": 1 }, "type": "roundrobin" }, "hosts": ["localhost.com"], "uri": "/hello"}'
$ curl http://127.0.0.1:9080/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{ "upstream": { "nodes": { "127.0.0.1:1981": 1 }, "type": "roundrobin" }, "hosts": ["test.com"], "uri": "/hello"}'
Test:
$ curl http://127.0.0.1:9080/hello -H 'host: localhost.com'1980
$ curl http://127.0.0.1:9080/hello -H 'host: test.com'1981
$ curl http://127.0.0.1:9080/hello{"error_msg":"404 Route Not Found"}
The host
rule matches, the request hits the corresponding upstream, and the host
does not match, the request returns a 404 message.
#
5. Parameter matchWhen 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 variablePlease 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 POST form attributesAPISIX supports filtering route by POST form attributes with Content-Type
= application/x-www-form-urlencoded
.
We can define the following route:
$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '{ "methods": ["POST"], "uri": "/_post", "vars": [ ["post_arg_name", "==", "json"] ], "upstream": { "type": "roundrobin", "nodes": { "39.97.63.215:80": 1 } }}'
The route will be matched when the POST form contains name=json
.
#
How to filter route by GraphQL attributesAPISIX 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
isquery
- The
graphql_name
isgetRepo
, - 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
.