Request Query and Path Manipulation
This demo is intended to demonstrate the APISIX capability, i.e., the ability to handle specific business logic in a programmable manner. No hint is included that it can be used in a production environment, where it should be solidified as a plugin and fully tested.
Prepare environment
Please refer to API7 EE Introduction to complete the environment preparation.
Configure the serverless plugin
Create a plugin template with the serverless-pre-function
plugin enabled with the following configuration as described in API7 EE Introduction.
{
"phase": "access",
"functions": [
"return function(conf, ctx) local core = require('apisix.core'); local company_id = core.request.get_uri_args(ctx).company or '000'; ngx.req.set_uri(ctx.var.uri .. '/' .. tostring(company_id)); end",
"return function(conf, ctx) local core = require('apisix.core'); local args = core.request.get_uri_args() or {}; args.company = nil; core.request.set_uri_args(ctx, args); end"
]
}
This actually defines two Lua code segments that are executed during the access phase, which will be executed sequentially and make some modifications to the request. Let's take it apart.
First part:
return function(conf, ctx)
-- import apisix core module
local core = require('apisix.core');
-- get company id from request's queries
local company_id = core.request.get_uri_args(ctx).company or '000';
-- rewrite client's request uri and add company_id to it
ngx.req.set_uri(ctx.var.uri .. '/' .. tostring(company_id));
end
-- This is just a demo snippet, which does not take into account the need to embed specific values in the middle of uri. Just like:
-- YES: /api?company=101 => /api/101
-- NO: /api/test?company=101 => /api/101/test
-- But I believe it has been demonstrated that APISIX can accomplish this level of modification with only the addition of the appropriate logic.
Second part:
return function(conf, ctx)
-- import apisix core module
local core = require('apisix.core');
-- get all request's queries
local args = core.request.get_uri_args() or {};
-- remove a specific value
args.company = nil;
-- write changed args object back to current request
core.request.set_uri_args(ctx, args);
end
Next you need to create the upstream and API as described in API7 EE Introduction and reference this plugin template in the API.
Test
curl 127.0.0.1/anything?company=101 -i -H "Host: example.com"
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 398
Connection: keep-alive
Date: Mon, 13 Mar 2023 07:24:43 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/2.13.2304
{
"args": {}, # the company in queries was removed
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "example.com",
"User-Agent": "curl/7.81.0",
"X-Amzn-Trace-Id": "Root=1-640ecfbb-100153ef15534ab913b7803d",
"X-Forwarded-Host": "example.com"
},
"json": null,
"method": "GET",
"origin": "172.17.0.1, 146.190.80.65",
"url": "http://example.com/anything/101" # the company id was writed to uri
}