Built-In Variables
Built-in variables in APISIX are pre-defined variables that can be directly referenced in configurations. They are often used in plugin configurations, route matching, and log customization.
APISIX supports three types of built-in variables:
- NGINX Variables
- APISIX Variables
- Custom Variables
These variables are evaluated in a given order.
NGINX Variables
NGINX provides a set of variables that can be used to access various request-specific information.
Some of the commonly used variables include:
upstream_addr
remote_addr
request_uri
server_name
uri
http_user_agent
See the complete list of NGINX variables for more information.
APISIX Variables
In addition to NGINX variables, APISIX offers a variety of built-in variables:
Variable Name | Description |
---|---|
post_arg_* | HTTP POST form data when the content type is application/x-www-form-urlencoded . The asterisk is to be replaced with the actual name of the POST form data. |
arg_* | URL query string. The asterisk is to be replaced with the actual query parameter name. |
http_* | HTTP request header. The asterisk is to be replaced with the actual name of the header. |
cookie_* | Request cookie. The asterisk is to be replaced with the actual name of the cookie. |
balancer_ip | Upstream server IP. |
balancer_port | Upstream server port. |
consumer_name | Consumer username. |
consumer_group_id | Consumer group ID. |
graphql_name | GraphQL operation name. |
graphql_operation | GraphQL operation type. |
graphql_root_fields | GraphQL root fields. |
route_id | Route ID. |
route_name | Route name. |
service_id | Service ID. |
service_name | Service name. |
resp_body | HTTP response body. |
mqtt_client_id | Client ID in MQTT protocol. |
redis_cmd_line | Redis command. |
rpc_time | RPC request round-trip time. |
Custom Variables
You can also register your own variables and use them as built-in variables. For instance, you can use custom variables to customize log format in logging plugins, or use them as keys in rate limiting plugins.
Example
The following example demonstrates two approaches for custom variable registration and how you can leverage the variable to obtain information from a route, subsequently logging the information to a remote server.
Create a Service
Create a service to configure http-logger
plugin and upstream:
curl "http://127.0.0.1:9180/apisix/admin/services" -X PUT \
-H 'X-API-KEY: ${ADMIN_API_KEY}' \
-d '{
"id":"srv_custom_var",
"plugins": {
"http-logger": {
"uri": "'"${REMOTE_SERVER_ADDR}"'"
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
}
}
}'
Register a Custom Variable
You can choose to register the custom variable in the source code or use the serverless
plugins.
Method 1: In the Source Code
Add the following snippet to your custom Lua file and source it to register a custom variable named a6_route_labels
. The variable represents the value of labels
in a request to a route, if available:
local core = require "apisix.core"
core.ctx.register_var("a6_route_labels", function(ctx)
local route = ctx.matched_route and ctx.matched_route.value
if route and route.labels then
return route.labels
end
return nil
end)
Start or reload APISIX accordingly. If APISIX is already running, send a PUT request to /apisix/admin/plugins/reload
to hot reload the plugins for changes to take effect.
While the snippet can technically be added anywhere the code is sourced, exercise caution when modifying the APISIX core codebase to avoid any negative impact on the standard functionalities.
It is recommended to keep your custom Lua code in a separate directory and source it by configuring extra_lua_path
and extra_lua_cpath
in the config.yaml
configuration file.
For more information, see create Lua plugin guide.
Method 2: In the serverless
Plugins
You can also register a custom variable using the serverless-pre-function
or serverless-post-function
serverless function plugins. These plugins run serverless functions before or after a specified execution phase, and you can register custom variables in these functions.
Add the serverless-pre-function
plugin to the previously created service, where the function registers the custom variable a6_route_labels
:
curl "http://127.0.0.1:9180/apisix/admin/services/srv_custom_var" -X PATCH \
-H 'X-API-KEY: ${ADMIN_API_KEY}' \
-d '{
"plugins": {
"serverless-pre-function": {
"phase": "rewrite",
"functions": [
"return function()
local core = require \"apisix.core\"
core.ctx.register_var(\"a6_route_labels\", function(ctx)
local route = ctx.matched_route and ctx.matched_route.value
if route and route.labels then
return route.labels
end
return nil
end);
end"
]
}
}
}'
Method 3: In _meta.prefunction
of Plugins
If you are using API7 Enterprise, you can use _meta.pre_function
to configure the custom code execution prior to each phase of plugin execution.
The following example will show you how to declares a _meta.pre_function
in the proxy-rewrite
plugin to extract the user_id
in the request path, register it as a variable, and use it to compose the new request path.
In order to use parameters in the route's URI, you should first update the router in the configuration file to be radixtree_uri_with_parameter
as it is not the default setting:
apisix:
router:
http: radixtree_uri_with_parameter
Then reload APISIX for changes to take effect.
Create a route to the httpbin service to examine the rewritten path:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "pre-func-route",
"uri": "/anything/:user_id/hello",
"plugins": {
"proxy-rewrite": {
"_meta": {
"pre_function": "
return function(conf, ctx)
local core = require \"apisix.core\"
core.ctx.register_var(\"user_id\", function(ctx) return ctx.curr_req_matched.user_id end)
end"
},
"uri": "/anything/$user_id/world"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ Match requests to /anything/:user_id/hello
where user_id
is a parameter.
❷ Customize the _meta.pre_function
to extract the user_id
value from the requested path and save it to a variable of the same name.
❸ Rewrite the request path to /anything/$user_id/world
, where $user_id
will be replaced by the variable value.
Send a request to the route:
curl -i "http://127.0.0.1:9080/anything/johndoe/hello"
You should observe the following response, showing the request path has been rewritten partially with the user_id
:
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "text/html..."
...
},
"json": null,
"method": "GET",
"origin": "127.0.0.1, 59.71.xxx.xxx",
"url": "http://127.0.0.1/anything/johndoe/world"
}
Configure Log Format
Create a plugin metadata object to configure log format for all http-logger
instances:
curl "http://127.0.0.1:9180/apisix/admin/plugin_metadata/http-logger" -X PUT \
-H 'X-API-KEY: ${ADMIN_API_KEY}' \
-d '{
"log_format": {
"host": "$host",
"client_ip": "$remote_addr",
"labels": "$a6_route_labels"
}
}'
❶ host
and remote_addr
: NGINX variables.
❷ a6_route_labels
: custom variable.
Create a Route in Service
Create a route in the service:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H 'X-API-KEY: ${ADMIN_API_KEY}' \
-d '{
"id":"route_custom_var",
"uri":"/get",
"service_id": "srv_custom_var",
"labels": {
"key": "test_a6_route_labels"
}
}'
❶ service_id
: correspond to the previously created service.
❷ labels
: route information to be logged with the custom variable.
Verify Custom Variable Registration
Send a request to verify that the custom variable logs the labels
information in route:
curl "http://127.0.0.1:9080/get"
You should see a log entry in your remote server created by a POST request with a body similar to the following:
[
{
"labels": {
"key": "test_a6_route_labels"
},
"service_id": "srv_custom_var",
"client_ip": "172.21.0.1",
"route_id": "route_custom_var",
"host": "127.0.0.1"
}
]
This verifies the custom variable was registered and it logs the labels
information in a route successfully.
Evaluation Order
APISIX evaluates variables in the given order:
- Custom Variables
- APISIX Variables
- NGINX Variables
If a variable is successfully sourced in custom variables, APISIX will not continue to look in APISIX variables or NGINX variables.
In other words, custom variables will overwrite variables of the same names defined in APISIX variables or NGINX variables, to better meet requirements of your specific use cases.