Apidog 允許你從 Javascript 環境執行外部程式(腳本、JAR、二進位檔)。這讓你能夠運用 Java、Python、PHP、Go、Shell 等語言中的既有程式碼。外部程式會在 Apidog 沙箱外執行,並且擁有對你系統的完整存取權。請確保你信任正在執行的程式碼。
支援的語言#
| 語言 | 副檔名 | 命令前綴 |
|---|
| Java | .jar | java -jar |
| Python | .py | python |
| Node.js | .js | node |
| PHP | .php | php |
| Go | .go | go run |
| Shell | .sh | sh |
| Ruby | .rb | ruby |
| Lua | .lua | lua |
如何呼叫外部程式#
1.
開啟外部程式目錄:點擊腳本編輯器中的資料夾圖示,以開啟應放置外部腳本的目錄。 2.
透過腳本執行:使用 pm.executeAsync 呼叫程式。 API 參考#
pm.executeAsync#
args string[] 參數。呼叫 jar 套件中的指定方法時,會使用 JSON.stringify 進行轉換。除此之外,非 string 型別會被隱式轉換為 string。
command string 外部程式的執行命令,「命令前綴」的第一部分就是執行命令。選填,預設值會自動推斷(請參閱上方「命令前綴」表格),也可自訂為任何程式。
cwd string 子程序的工作目錄。選填,預設為「外部程式目錄」。
env Record<string, string> 子程序的環境變數。選填,預設為 {}。
windowsEncoding string Windows 系統上使用的編碼。選填,預設為 "cp936"。
className string 指定要在 jar 套件中呼叫的類別名稱,例如 "com.apidog.Utils"。
method string 指定要在 jar 套件中呼叫的方法名稱,例如 "add"。
paramTypes string[] 指定要在 jar 套件中呼叫的方法參數型別,例如 ["int", "int"]。
預設情況下,Apidog 會使用 python 執行 .py 檔案。如果電腦上已安裝 python3,可以將 command 指定為 python3。 pm.execute#
pm.execute(filePath, args, options)args string[] 參數。呼叫 jar 套件中的指定方法時,會使用 JSON.stringify 進行轉換。除此之外,非 string 型別會被隱式轉換為 string。
windowsEncoding string Windows 系統上使用的編碼。選填,預設為 "cp936"。
className string 指定要在 jar 套件中呼叫的類別名稱,例如 "com.apidog.Utils"。
method string 指定要在 jar 套件中呼叫的方法名稱,例如 "add"。
paramTypes string[] 指定要在 jar 套件中呼叫的方法參數型別,例如 ["int", "int"]。
執行與日誌#
執行程式時,已執行的命令會列印在主控台中(僅供參考)。如果結果不符合預期,你可以複製該命令並貼到 Shell/CMD 中進行偵錯。主控台也會列印已執行程序的「標準輸出(stdout)」和「標準錯誤輸出(stderr)」。stdout 內容(不包含結尾換行字元)將會作為執行的最終結果。基於歷史原因,當 stderr 中有內容時,pm.execute 會將執 行視為失敗。這會導致某些程式在輸出警告或錯誤訊息時失敗。pm.executeAsync 改為使用程序的 exit code 來判斷執行是否失敗。
外部程式的輸入與輸出#
由於指定的外部程式是透過命令列執行,因此它只能透過命令列引數取得傳入的參數。例如,在腳本 pm.executeAsync('add.js', [2, 3]) 中,實際執行的命令是 node add.js 2 3。若要在外部腳本 add.js 中取得參數:1.
不同程式語言取得命令列引數的方式不同,請參閱對應語言的文件。
2.
命令列引數的型別一律為 string,需要依據實際型別進行轉換。
回傳值#
如上所述,Apidog 會使用 stdout 內容作為程式執行結果。因此,將內容列印到 stdout 即可回傳結果。例如,在腳本 const result = await pm.executeAsync('add.js', [2, 3]) 中,可以透過以下方式回傳結果:1.
不 同程式語言列印到 stdout 的方式不同,請參閱對應語言的文件。
2.
回傳型別為 string,需要依據實際型別進行轉換。
4.
呼叫 jar 套件中的指定方法時,被呼叫方法的回傳值會作為最終回傳值。
拋出錯誤#
1.
不同程式語言拋出錯誤的方式不同,請 參閱對應文件。
2.
在 JavaScript 中,console.error('Error') 只會列印到 stderr,而不是拋出錯誤。使用其他語言時也請注意這一點。
偵錯資訊#
由於 pm.executeAsync 使用 exit code 而不是 stderr 來判斷成功與否,因此 stderr 可用來列印偵錯資訊,且不會影響執行。1.
只有 pm.executeAsync 支援這種列印偵錯資訊的方式。
2.
不同程式語言列印到 stderr 的方式不同,請參閱對應文件。
從 pm.execute 遷移到 pm.executeAsync#
由於 pm.executeAsync 的回傳值是 Promise 型別,無法直接將 execute 改成 executeAsync。但你可以使用 async/await 以最少變更進行遷移。Apidog 版本 2.3.24 或更新版本(CLI 版本 1.2.38 或更新版本)支援 top-level await。
1.
將 execute 改為 executeAsync
呼叫 .jar 套件中的指定方法#
此功能要求 Apidog 版本為 2.1.39 或更新版本。它僅支援透過反射呼叫 jar,不支援像 Spring Boot 這類使用內部執行階段反射的 jar。
預設情況下,呼叫 jar 會執行 Main 類別中的 main 方法。如果指定了 options.className,它會覆寫預設行為,改為呼叫 jar 中的指定方法。呼叫 jar 中的指定方法與其他外部程式不同。Apidog 會使用內建執行器,透過反射在 jar 中尋找方法並呼叫它。如果被呼叫的方法有回傳值,轉換為字串後會作為最終回傳值。否則,其行為與其他呼叫相同,使用 stdout 內容作為回傳值。其中 <app-dist>/assets/JarExecuter-1.1.0-jar-with-dependencies.jar 是內建執行器,負責透過反射在使用者程式 ./scripts/jar-1.0-SNAPSHOT.jar 中尋找方法 com.apidog.Test.combine(String,String),並使用參數(JSON 字串)"hello" 和 "world" 呼叫它。paramTypes 為選填。如果未指定,型別會根據參數自動推斷。整數會推斷為 "int",浮點數推斷為 "double",布林值推斷為 "boolean",字串推斷為 "String",陣列則會根據第一個元素推斷,例如 [3] 會推斷為 "int[]",[3.14] 會推斷為 "double[]",依此類推。
如果推斷的型別與被呼叫方法的實際參數型別不符,則需要手動指定 paramTypes。
paramTypes 陣列中支援的值:"Number"、"int"、"Integer"、"long"、"Long"、"short"、"Short"、"float"、"Float"、"double"、"Double"、"boolean"、"Boolean"、"String"、"Number[]"、"int[]"、"Integer[]"、"long[]"、"Long[]"、"short[]"、"Short[]"、"float[]"、"Float[]"、"double[]"、"Double[]"、"boolean[]"、"Boolean[]"、"String[]"因此,上方範例中的 paramTypes 可以省略:1. PHP 程式#
2. Jar 程式#
常見問題#
1. 某些程式需要專案設定檔,若缺少則會發生錯誤#
could not find `Cargo.toml` in `<...>/ExternalPrograms` or any parent directory
go.mod file not found in current directory or any parent directory; see 'go help modules'
解決方案:使用 pm.executeAsync 並指定 cwd。2. MacOS 內建 Python 3,但沒有 Python 2#
使用 pm.executeAsync 並將 command 設為 "python3"。3. 找不到 Command xxx#
安裝對應程式,並將必要目錄加入系統 PATH。Java 安裝請參閱 docs。4. 在某些 Windows 系統上呼叫外部腳本時列印出亂碼#
將 windowsEncoding 設為 'utf-8'