Skip to main content
Version: 2.8.1

Request Transformer

Request Transformer

用途說明#

此插件可以在請求到達上游服務器之前,將請求進行簡單的轉換。

這些轉換可以是簡單的替換,也可以是使用正規表達式匹配傳入請求部分的複雜轉換,會將匹配的字符串保存到變量中,再使用彈性的模板將這些字符串替換為轉換後的請求。

欄位配置說明#

啟用時可以看到以下畫面:

插件啟用配置圖

對應的配置說明如下:

參數類型預設值說明必填
http_methodstring設定上游請求的 HTTP 方法。
remove.headersarray of string標頭名稱列表。
對上游請求前,會將對應到的標頭名稱移除。
V
remove.querystringarray of string字符串名稱列表。
對上游請求前,會將對應之字符串名稱移除。
V
remove.bodyarray of string參數名稱列表。
僅當 content-type 為以下其中之一:application/jsonmultipart /form-dataapplication/x-www-form-urlencoded且參數名稱存在時,才刪除該參數。
V
replace.uristring使用此設定值更新上游請求 URI。
該值只能用於更新 URI 的路徑部分,而不能用於配置或主機名。
V
replace.bodyarray of string參數名稱:值的列表。格式需照「參數名稱:值」的方式來設定。
僅當 content-type 為以下其中之一:application/jsonmultipart /form-dataapplication/x-www-form-urlencoded,且若參數名稱已經存在,才會使用該參數名稱所對應的值來取代;若該參數名稱不存在,則會忽略。
V
replace.headersarray of string標頭名稱:值的列表。格式需照「標頭名稱:值」的方式來設定。
若標頭名稱已經存在,才會使用該標頭名稱所對應的值來取代;若該標頭名稱不存在,則會忽略。
V
replace.querystringarray of string查詢字串名稱:值的列表。格式需照「查詢字串名稱:值」的方式來設定。
若查詢字串名稱已經存在,才會使用該查詢字串名稱所對應的值來取代;若該查詢字串名稱不存在,則會忽略。
V
rename.headersarray of string標頭名稱:值的列表。格式需照「標頭名稱:值」的方式來設定。
若標頭名稱已經存在,才會將該標頭名稱更名;若該標頭名稱不存在,則會忽略。
V
rename.querystringarray of string查詢字串名稱:值的列表。格式需照「查詢字串名稱:值」的方式來設定。
若查詢字串名稱已經存在,才會將該查詢字串名稱改名;若該查詢字串名稱不存在,則會忽略。
V
rename.bodyarray of string參數名稱:值的列表。格式需照「參數名稱:值」的方式來設定。
僅當 content-type 為以下其中之一:application/jsonmultipart /form-dataapplication/x-www-form-urlencoded,且若參數名稱已經存在,才會將該參數名稱更名;若該參數名稱不存在,則會忽略。
V
add.headersarray of string標頭名稱:值的列表。格式需照「標頭名稱:值」的方式來設定。
只有當標頭名稱不存在的時候,才會使用設定值來設置一個新的標頭名稱;若該標頭名稱已存在,則會忽略。
V
add.querystringarray of string查詢字串名稱:值的列表。格式需照「查詢字串名稱:值」的方式來設定。
只有當查詢字串名稱不存在的時候,才會使用設定值來設置一個新的查詢字串名稱;若該查詢字串名稱已存在,則會忽略。
V
add.bodyarray of string參數名稱:值的列表。格式需照「參數名稱:值」的方式來設定。
僅當content-type為以下其中之一:application/jsonmultipart /form-dataapplication/x-www-form-urlencoded,且當參數名稱不存在的時候,才會使用設定值來設置一個新的參數名稱(使用表單編碼);若該參數名稱已存在,則會忽略。
V
append.headersarray of string標頭名稱:值的列表。格式需照「標頭名稱:值」的方式來設定。
當標頭名稱不存在的時候,會使用設定值來設置一個新的標頭名稱。若該標頭名稱已存在,則會附加一個設定值的標頭名稱。
V
append.querystringarray of string查詢字串名稱:值的列表。格式需照「查詢字串名稱:值」的方式來設定。
當查詢字串名稱不存在的時候,會使用設定值來設置一個新的查詢字串名稱。若該查詢字串名稱已存在,則會附加一個設定值的查詢字串名稱。
V
append.bodyarray of string參數名稱:值的列表。格式需照「參數名稱:值」的方式來設定。
僅當 content-type 為以下其中之一:application/jsonapplication/x-www-form-urlencoded,且當參數名稱不存在的時候,會使用設定值來設置一個新的參數名稱。若該參數名稱已存在,則會把兩個值(原本對應的值 和 新的設定值)匯總到一個陣列 (array) 內。
V
注意事項
  • 如果設定值含有 ,,則不能使用逗號分隔的列表格式。
  • X-Forwarded-* 之名稱是 Nginx 編寫的非標準標頭名稱,用於向上游通知客戶端詳細訊息,無法被此插件所轉換。

實際執行配置的順序#

插件會按照以下順序之配置來執行請求的轉換:

remove → rename → replace → add → append

模板值設定說明#

你可以使用任何當前請求的標頭、查詢字串參數、和取得的 URI groups 作為模板值,來結合上述所說的欄位配置說明

請求參數模板值
header$(headers.<header_name>)$(headers["<Header-Name>"])$(headers["<header-name>"]))
querystring$(query_params.<query-param-name>)$(query_params["<query-param-name>"]))
captured URIs$(uri_captures.<group-name>)$(uri_captures["<group-name>"]))

要跳脫原模板的話,可以把模板值使用兩個單引號包覆,再放入原模板內,如:$('$(some_escaped_template)')

模板值進階說明#

內容為 $(...) 的佔位符被評估為 Lua 表達式,因此可以使用邏輯運算符號,例如:

Header-Name:$(uri_captures["user-id"] or query_params["user"] or "unknown")

首先會查找路徑參數 (uri_captures),如果找不到,則返回 查詢字串參數 (query_params)。假設兩者都不存在,則會回一個預設值:unknown

可以將常量指定為動態佔位符之外的模板值的一部分。例如,從查詢字串 (query_params) 名為 auth 的參數來創建一個基本身份驗證標頭,而該標頭僅包含 base64 編碼的部分:

Authorization:Basic $(query_params["auth"])
注意事項

特別注意,在多行的模板中(像是上方的範例),請確保沒有添任何句尾的空白或是換行符號。因為這些空白及符號是位於佔位符之外,會被附加到生成的值上。

該環境是沙盒環境,意思是 Lambdas 除了字符串方法(string method)(如上述範例中的sub())之外,無法訪問其他任何的元件庫函數。

用法示例#

在全局啟用插件#

  1. 從網站左邊 Menu 中 外掛插件 頁面中,點選右上角的 新增外掛插件

全局啟用畫面

  1. 點選後,選擇 轉換 頁籤,並啟用 Request Transformer,填寫內容參考欄位配置說明,設定成功後,任何請求(不分服務、路由、用戶)的請求轉換都會生效。

在服務端上啟用插件#

  1. 從網站左邊 Menu 中 服務 > 服務列表 頁面中,選擇要啟用此插件的服務,假設為 google,點選對應的編輯按鈕:

服務啟用畫面1

  1. 在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

服務啟用畫面2

點選後,選擇 轉換 頁籤,並啟用 Request Transformer,填寫內容參考欄位配置說明,設定成功後,僅有此服務(範例為google)的請求轉換會生效。

在路由端上啟用插件#

可以由兩種方式來選擇路由,並啟用插件:

方式一:路由列表#

  1. 從網站左邊 Menu 中 服務 > 路由列表 頁面中,選擇要啟用此插件的路由,假設為 google,點選對應的編輯按鈕:

路由啟用畫面1

方式二:服務 > 服務列表 > 路由列表#

  1. 從網站左邊 Menu 中 服務 > 服務列表 頁面中,選擇要啟用此插件的路由 所屬之服務(假設為 google),點選對應的編輯按鈕。

在編輯畫面中,點選上方的 路由 頁籤,選擇要啟用此插件的路由(假設為 google),點選對應的編輯按鈕:

路由啟用畫面2


  1. 承第1步,點擊上述兩種方式之一的編輯按鈕後,在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

路由啟用畫面3

點選新增外掛插件 按鈕後,選擇 轉換 頁籤,並啟用 Request Transformer,填寫內容參考欄位配置說明,設定成功後,僅有此路由(範例為google)的請求轉換會生效。

在用戶端上啟用插件#

  1. 從網站左邊 Menu 中 訂閱用戶 > 用戶列表 頁面中,選擇要啟用此插件的用戶,假設為 portaladmin,點選對應的編輯按鈕:

用戶啟用畫面1

  1. 在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

用戶啟用畫面2

點選後,選擇 轉換 頁籤,並啟用 Request Transformer,填寫內容參考欄位配置說明,設定成功後,僅有此用戶(範例為 portaladmin)的請求轉換會生效。

使用模板作為設定值的範例#

假設我有註冊一個名為 backend 的服務,此服務的回覆會將目前收到請求的路徑、標頭、內文全部都放在回應內。

先在該服務上啟用插件:

  1. add 的區塊的 headers 欄位填入: x-consumer-id:$(headers['x-user-id'] or 'alice')

  2. remove 的區塊的 headers 欄位填入: x-user-id

  3. 送出新增插件成功

接著,試著使用 GOC API Gateway 去呼叫該 backend 的服務,如下:

curl -XGET < GOC API Gateway protocol>://< GOC API Gateway ip>:< GOC API Gateway port>/forward \
-H 'x-user-id: Foo' \
-H 'X-API-HOST: backend' | json_pp
{
"path" : "/forward",
"header" : {
"user-agent" : "curl/7.65.3",
"x-forwarded-proto" : "http",
"x-api-host" : "backend",
"x-forwarded-path" : "/forward",
"host" : "172.35.1.146",
"accept" : "*/*",
"connection" : "keep-alive",
"x-consumer-id" : "Foo",
"x-forwarded-host" : "localhost",
"x-real-ip" : "172.18.0.1",
"x-forwarded-for" : "172.18.0.1",
"x-forwarded-port" : "8000"
},
"body" : {}
}

可以看到收到的標頭中, x-consumer-id 的標頭值對應的就是傳入的 x-user-id ,而 x-user-id 這個標頭同時也被移除,看不到了。

假設再呼叫一次 backend 的服務,但不帶入 x-user-id 的標頭:

curl -XGET < GOC API Gateway protocol>://< GOC API Gateway ip>:< GOC API Gateway port>/forward \
-H 'X-API-HOST: backend' | json_pp
{
"path" : "/forward",
"header" : {
"user-agent" : "curl/7.65.3",
"x-forwarded-proto" : "http",
"x-api-host" : "backend",
"x-forwarded-path" : "/forward",
"host" : "172.35.1.146",
"accept" : "*/*",
"connection" : "keep-alive",
"x-consumer-id" : "alice",
"x-forwarded-host" : "localhost",
"x-real-ip" : "172.18.0.1",
"x-forwarded-for" : "172.18.0.1",
"x-forwarded-port" : "8000"
},
"body" : {}
}

可以看到,因為沒有傳入 x-user-id ,所以預設會在 x-consmer-id 標頭填入 alice 的值。

驗證#

請參考使用模板作為設定值的範例的內容來進行驗證。