メインコンテンツまでスキップ

外部プログラムの呼び出し

ヒント

外部プログラムは「サンドボックス環境」の外で実行されるため、コンピュータ上の他のプログラム、ファイル、データにアクセスして操作する権限を持ち、一定のセキュリティリスクがあります。使用者は呼び出されるプログラムの安全性を必ず確認してください。

外部プログラムは、「外部プログラムディレクトリ」下に保存されているコードファイルで、Javaプログラムのアーカイブファイルjarパッケージのほか、他のプログラムのコードソースファイルを使用できます。拡張子が .jar、.py、.php、.js、.bsh、.go、.sh、.rb、.lua、.rs、.py などのファイルをサポートしています。以下の方法で「外部プログラムディレクトリ」をすぐに開くことができます。

外部プログラムの呼び出し

外部プログラムを呼び出すとき、Apidogはサブプロセスを起動し、その中でコマンドライン実行方式でユーザー指定の外部プログラムを実行し、最後にサブプロセスの標準出力(stdout)を呼び出しの戻り値として取得します。プロセス全体で、コアロジックはユーザーが外部プログラム内で実装し、apidog は主に以下の3ステップの作業を行います:

  • ユーザー指定のパラメータからコマンド文字列を組み立てる

  • コマンドを実行する

  • 結果を返す

これらのステップのうち、呼び出し方法の原理を理解するのは最初のステップです。Apidogが使用するコマンド結合公式は以下の通りです: 「コマンドプレフィックス + Scriptパス + パラメータリスト」になります。

その中で、「コマンドプレフィックス」 はプログラムファイルの拡張子から推測されます。「Scriptパス」と「パラメータリスト」はユーザーが呼び出し時に指定します。

例: スクリプトpm.execute('com.apidog.Base64EncodeDemo.jar', ['abc','bcd'])、 実際に実行されるコマンドはjava -jar "com.apidog.Base64EncodeDemo.jar" "abc" "bcd"になります。両者の変換関係は図のようになります:

外部プログラムの呼び出し

プログラムの拡張子とコマンドプレフィックスの関係:

言語コマンドプレフィックスScript拡張子
Javajava -jar.jar
Pythonpython.py
PHPphp.php
JavaScriptnode.js
BeanShelljava bsh.Interpreter.bsh
Gogo run.go
Shellsh.sh
Rubyruby.rb
Lualua.lua
Rustcargo run.rs

API

pm.executeAsync

pm.executeAsync(filePath, args, options)

  • filePath string 外部プログラムのパス

  • args string[] パラメータ。jarパッケージ内の指定されたメソッドを呼び出す場合は、JSON.stringify を使用して変換されます。それ以外の場合、文字列型ではない型は暗黙的に文字列型に自動変換されます。

  • options Object

    • command string 外部プログラムの実行コマンド。「コマンドプレフィックス」の最初の部分が実行コマンドです。必須ではありません。デフォルトは自動的に推測された値(上記の「コマンドプレフィックス」表を参照)ですが、任意のプログラムにカスタマイズできます。

    • cwd string サブプロセスのワーキングディレクトリ。必須ではありません。デフォルトは「外部プログラムディレクトリ」です。

    • env Record<string, string> サブプロセスの環境変数。必須ではありません。デフォルトは {} です。

    • windowsEncoding string Windows システムで使用するエンコーディング形式。必須ではありません。デフォルトは "cp936" です。

    • className string jar パッケージ内で呼び出すクラス名を指定します。例:"com.apidog.Utils"。必須ではありません。jarパッケージ内の指定されたメソッドの呼び出しを参照してください。

    • method string jar パッケージ内で呼び出すメソッド名を指定します。例:"add"。必須ではありません(className が値を持つ場合は必須)。jarパッケージ内の指定されたメソッドの呼び出し を参照してください。

    • paramTypes string[] jar パッケージ内で呼び出すメソッドのパラメータ型を指定します。例: ["int", "int"]。必須ではありません。デフォルトはパラメータから自動的に推論します。jarパッケージ内の指定されたメソッドの呼び出し を参照してください。

  • 戻り値: Promise

ヒント

command パラメータの使用場面:

Apidogはデフォルトで .py ファイルを python で実行しますが、コンピュータに python3 がすでにインストールされている場合は、commandpython3 に指定できます。

pm.executeAsync('./demo.py', [], { command: 'python3' }).then(res => {
console.log('result: ', res);
});

pm.execute

ヒント

pm.executeAsync を使用することをおすすめします。詳細は《コードの移行説明》を参照してください。

pm.execute(filePath, args, options)

  • filePath string 外部プログラムのパス

  • args string[] パラメータ。jarパッケージ内の指定されたメソッドを呼び出す場合は、JSON.stringify を使用して変換されます。それ以外の場合、文字列型ではない型は暗黙的に文字列型に自動変換されます。

  • options Object

    • windowsEncoding string Windows システムで使用するエンコーディング形式。必須ではありません。デフォルトは "cp936" です。

    • className string jar パッケージ内で呼び出すクラス名を指定します。例:"com.apidog.Utils"。必須ではありません。jarパッケージ内の指定されたメソッドの呼び出し を参照してください。

    • method string jar パッケージ内で呼び出すメソッド名を指定します。例:"add"。必須ではありません(className が値を持つ場合は必須)。jarパッケージ内の指定されたメソッドの呼び出し を参照してください。

    • paramTypes string[] jar パッケージ内で呼び出すメソッドのパラメータ型を指定します。例: ["int", "int"]。必須ではありません。デフォルトはパラメータから自動的に推論します。jarパッケージ内の指定されたメソッドの呼び出し を参照してください。

  • 戻り値: string

実行とログ

プログラムの実行時に、実行されたコマンドの内容がコンソールに出力されます(内容は参考用)。実行結果が期待されたものと異なる場合、コマンドの内容をコピーしてShell/CMDに貼り付け、デバッグを実行できます。

コンソールには、プログラム実行プロセスの「標準出力(stdout)」と「標準エラー出力(stderr)」も出力されます。「標準出力」のすべての内容(最後の改行を除く)が、プログラムの最終的な実行結果となります。

ヒント

歴史的な理由から、pm.execute は「標準エラー出力」に内容がある場合にプログラムの実行が失敗したと判断します。これにより、一部のプログラムが warning や error 情報を出力した場合に、実行が失敗することがあります。pm.executeAsync は終了コードを使用して、プログラムの実行が成功したかどうかを判断するように変更されています。

外部プログラムの呼び出し

外部プログラムの入力と出力

パラメータ

ユーザー指定の外部プログラムがコマンドライン実行方式で実行されるため、外部プログラムはコマンドラインパラメータから実行時に渡されたパラメータのみを取得できます。

例えば、スクリプト pm.executeAsync('add.js', [2, 3]) を実行すると、実際のコマンドは node add.js 2 3 となります。外部スクリプト add.js 内でパラメータを取得するには、以下のようにします:

let a = parseInt(process.argv[1]); // 2  
let b = parseInt(process.argv[2]); // 3
ヒント

プログラミング言語によって、コマンドラインパラメータの取得方法は異なります。詳細は各言語のドキュメントを参照してください。 コマンドラインパラメータの型はすべて文字列なので、必要に応じて型変換が必要です。

戻り値

前述のとおり、Apidogはプログラム呼び出しの結果として標準出力(stdout)の内容を使用するため、標準出力に内容を出力することで結果を返すことができます。

例えば、スクリプト const result = await pm.executeAsync('add.js', [2, 3]) の場合、以下のように出力して変数 result に割り当てることができます:

console.log(parseInt(process.argv[1]) + parseInt(process.argv[2]));
ヒント

プログラミング言語によって、標準出力(stdout)への出力方法は異なります。詳細は各言語のドキュメントを参照してください。 戻り値の型は文字列なので、必要に応じて型変換が必要です。 戻り値の末尾にある改行は自動的に削除されます。 jar パッケージ内の指定されたメソッドを呼び出す場合、呼び出されたメソッドの戻り値が最終的な戻り値として優先されます。

エラーのスロー

現在のタスクを失敗させて実行を終了するには、エラーをスローします。例:

throw Error("Execution failed");
ヒント

プログラミング言語によって、エラーのスロー方法は異なります。詳細は各言語のドキュメントを参照してください。 JavaScript のコード console.error('Error') はエラーのスローではなく、標準エラー出力(stderr)への出力です。他の言語も同様に注意が必要です。

デバッグ情報

pm.executeAsync は終了コードを使用してプログラムの成功/失敗を判断するため、標準エラー出力(stderr)を使用してデバッグ情報を出力できます。プログラムの実行に影響しません。

例:

console.warn("debug info");  
console.error("error info");
ヒント

pm.executeAsync インターフェイスのみがこの方法でのデバッグ情報の出力をサポートしています。 プログラミング言語によって、標準エラー出力(stderr)への出力方法は異なります。詳細は各言語のドキュメントを参照してください。

pm.execute から pm.executeAsync への移行

pm.executeAsync の戻り値が Promise 型なので、古いコードの execute をそのまま executeAsync に置き換えることはできません。しかし、async/await を使用することで、最小限の変更でコードを移行できます。

ヒント

Apidogはトップレベルの await をサポートしています。

具体的な方法は以下の通りです:

  1. executeexecuteAsync に変更する
  2. 関数呼び出しの前に await キーワードを追加する
// 変更前  
const result = pm.execute("add.js", [3, 4]);
pm.environment.set("result", result);

// 変更後
const result = await pm.executeAsync("add.js", [3, 4]);
pm.environment.set("result", result);

Jarパッケージ内の指定メソッドの呼び出し

ヒント

この機能は、反射を使って直接呼び出せるJarパッケージのみをサポートし、Spring Bootのような内部ランタイムによる反射呼び出しを行うJarパッケージはサポートしていません。

外部プログラムがJarパッケージの場合、デフォルトではJar内のMainクラスのmainメソッドが呼び出されます。パラメータoptions.classNameに値が指定されている場合は、デフォルトの動作を無視して、Jar内の指定されたメソッドを呼び出します。

Jar内の指定メソッドの呼び出しは、他の外部プログラムの呼び出しとは異なります。apidogは、ビルトインの実行器を使用して、反射によりJar内のメソッドを検索して呼び出します。また、呼び出されたメソッドが戻り値を持つ場合、その戻り値(文字列に変換)を最終的な戻り値として返します。それ以外の場合は、他の呼び出し方式と同様に、標準出力(stdout)の内容を戻り値として返します。

例:

await pm.executeAsync('./scripts/jar-1.0-SNAPSHOT.jar', ['hello', 'world'], {
className: 'com.apidog.Test',
method: 'combine',
paramTypes: ['String', 'String']
})

実際に呼び出されるコマンドは:

java -jar "<app-dist>/assets/JarExecuter-1.1.0-jar-with-dependencies.jar" ./scripts/jar-1.0-SNAPSHOT.jar "com.apidog.Test.combine(String,String)" "\"hello\"" "\"world\""

ここで、<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 パラメータを省略できます。

await pm.executeAsync('./scripts/jar-1.0-SNAPSHOT.jar', ['hello', 'world'], {
className: 'com.apidog.Test',
method: 'combine'
})

1. php プログラム

スクリプトの内容:

const param1 = { a: 1, b: 2 }
const resultString = await pm.executeAsync('test.php', [JSON.stringify(param1)])
const result = JSON.parse(resultString)
console.log('実行結果:', result) // 実行結果:{ a: 2, b: 4 }

test.php のコード:

<?php
$param = json_decode($argv[1]);
$result = [];
foreach($param as $key=>$value) {
$result[$key] = $value * 2;
}
echo json_encode($result);

2. jar プログラム

スクリプトの内容:

const result = await pm.executeAsync('com.apidog.utils.jar', [3, 5], {
className: 'com.apidog.utils.Utils',
method: 'add',
paramTypes: ['Integer', 'Integer']
})
console.log('実行結果:', result) // 実行結果:8

com.apidog.utils.jar パッケージのコード:

package com.apidog.utils;

public class Utils {
public Integer add(Integer a, Integer b) {
return a + b;
}
};

よくある質問

1. 一部のプログラムはプロジェクトの設定ファイルが必要で、見つからないとエラーになる

例: rust と go

rust:

could not find `Cargo.toml` in `<...>/ExternalPrograms` or any parent directory

go:

go.mod file not found in current directory or any parent directory; see 'go help modules'

解決策: pm.executeAsyncインターフェースを使用し、cwd を指定

2. MacOSにはビルトインのPython3があるが、Python2はない

pm.executeAsyncインターフェースを使用し、パラメータ command の値を "python3" に設定

3. xxxコマンドが見つからない

対応するプログラムをインストールし、必要なディレクトリをオペレーティングシステムの PATH に追加。Java のインストールはドキュメントを参照。

4. 一部のWindowsシステムで外部スクリプトを参照すると、日本語が文字化けする

windowsEncoding パラメータの値を 'utf-8' に設定

var result = pm.execute(`hello.go`, [], { windowsEncoding: 'utf-8' })