'Transform request data in Krakrnd with lua
Using Krakend as api gateway.
I have an endpoint configured in krakend.json:
"endpoint":"/call",
"extra_config":{
"github.com/devopsfaith/krakend-lua/proxy":{
"sources":[
"/function.lua"
],
"pre":"pre_backend(request.load())",
"live":true,
"allow_open_libs":true
}
},
"method":"POST",
"output_encoding":"json",
"headers_to_pass":[
"*"
],
"backend":[
{
"url_pattern":"/api/v1/get_client_id",
[...]]
},
The endopont "/api/v1/get_client_id" recives just a param:
{"user_mail_1":"[email protected]"}
I want, whith the lua script my endopoint "/call" recives:
{"email":"[email protected]"}
and transform on before send:
{"user_mail_1":"[email protected]"}
I tried with gsub, but use body() as "string" is no efficient.
function pre_backend( req )
print('--Backend response, pre-logic:');
local r = req;
r:params('test','test');
r:query('lovelyquery')
r:body('test','test');
lolcal v = r:body():gsub('email', 'user_mail_1')
...
Is a way to parse "req" as a table, dict or something i can transform data?
Is another way to transform REQUEST data?
EXAMPLE WORKING WITH GSUB:
function pre_backend( req )
print('--Backend response, pre-logic:');
print('--req');
print(req);
print(type(req));
local r = req;
print('--body');
print(type(r:body()));
print(r:body())
local body_transformed = r:body():gsub('email', 'user_mail_1');
print('--body_transformed');
print(body_transformed);
print(type(body_transformed));
end
Console output:
2022/02/11 09:59:52 DEBUG: [http-server-handler: no extra config]
--Backend response, pre-logic:
--req
userdata: 0xc0004f9b60
userdata
--body
string
{"email" : "[email protected]","test_field":"email"}
--body_transformed
{"user_mail_1" : "[email protected]","test_field":"user_mail_1"}
string
As we can see the gsub is not efficient becouse replace all strings. If I can work with req as table, dict or something similar, I can replace dict key/value. ex: req['xxx] = 'xxx' or iterate req.keys
Solution 1:[1]
gsub stands for global substitution. It replaces all occurances of the pattern in the string.
If you just want to replace "email" infront of an email address simply use a pattern that takes this into account.
print((r:body():gsub('(")(email)("%s-:%s-"%w+@%w+%.%w+")', "%1user_mail_1%3")))
Alternatively if you knwo that you only want to replace the first occurance of email you can simply do this:
print((r:body():gsub("email", "user_mail_1", 1)))
The thrid parameter will stop gsub after the first replacement.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Piglet |
