MATLAB 関数実行のための RESTful API
MATLAB® 関数実行のための MATLAB Production Server™ RESTful API を使用すると、MATLAB データ型およびプロトコル バッファーの JSON 表現を使用してリモート サーバー上で MATLAB 関数を評価できます。プロトコル バッファーのサポートは、Java® クライアント API および .NET クライアント API でのみ提供されています。
MATLAB Production Server RESTful API を使用するクライアント コードを JavaScript® などの Web ベースの言語で記述して、HTML ページに組み込むことができます。その後、これらの Web ページを使用してリクエストを送信し、MATLAB Production Server インスタスからレスポンスを取得できます。Web ベースのアプリケーションは JavaScript で記述されたクライアント コードに適している可能性がありますが、Java、Python®、C++、.NET など任意の HTTP 対応プログラミング言語を使用してクライアント アプリケーションを開発することもできます。
クライアント プログラムが異なるドメインからリクエストを行う場合、JavaScript を使用するプログラマは、オリジン間リソース共有 (CORS) がサーバー上で有効になっているかどうかを確認する必要があります。サーバー上で CORS を有効にするには、サーバー管理者が main_config サーバー構成ファイルの cors-allowed-origins プロパティに適切な値を設定する必要があります。
RESTful API の特性
MATLAB 関数実行のための RESTful API は、MATLAB Production Server との通信に HTTP リクエスト/レスポンスモデルを使用します。このモデルには、リクエスト メソッド、レスポンスコード、メッセージ ヘッダー、およびメッセージ本文が含まれます。RESTful API には以下の特性があります。
HTTP メソッド (POST、GET、および DELETE) がクライアントとサーバー間の通信の基本モードを形成します。
一意の Uniform Resource Identifier (URI) が、サーバーによって作成されるリソースを特定します。
メッセージ ヘッダーが、リクエストの "コンテンツ タイプ" などのメタデータを伝達します。
API は
application/jsonを HTTPContent-Typeヘッダーとしてサポートします。また、MATLAB 関数実行のための RESTful API は、Java クライアント API および .NET クライアント API を介してのみ、
application/x-google-protobufを HTTPContent-Typeとしてサポートします。
リクエストのメッセージ本文には、サーバーに送信される情報が含まれます。
JSON をデータ シリアル化形式として使用する場合、デプロイされたアーカイブ内に含まれる MATLAB 関数への入力は JSON で表現され、メッセージ本文内にカプセル化されます。詳細については、MATLAB データ型の JSON 表現を参照してください。
データ シリアル化にプロトコル バッファー (protobuf) を使用する場合、Java クライアント ライブラリおよび .NET クライアント ライブラリにより、protobuf メッセージを proto 形式に基づいて内部的に作成して対応するバイト配列を返すためのヘルパー クラスが提供されます。このバイト配列をリクエストのメッセージ本文に使用します。
レスポンスのメッセージ本文には、リクエストに関する状態や結果などの情報が含まれます。
データ シリアル化に protobuf を使用する場合、Java クライアント ライブラリおよび .NET クライアント ライブラリにより、protobuf のレスポンスを逆シリアル化するためのメソッドとクラスが提供されます。
API はサーバーの同期モードと非同期モードの両方をサポートします。
メモ
以下の例および図では、JSON をデータ シリアル化形式として使用しています。
同期実行
同期モードでは、クライアントがリクエストを POST 送信すると、元のリクエストの処理を完了するまで、サーバーのワーカー プロセスが以降のすべてのリクエストをブロックします。処理が完了すると、ワーカーは自動的にクライアントにレスポンスを返します。リクエスト処理中にブロックするのはワーカーであるため、使用可能な他のワーカーが存在する場合、サーバーは他の同期リクエストを処理のために受け入れることができます。サーバーに対して同期リクエストを行ってレスポンスを待機するには、POST Synchronous Requestを使用します。
次の図は、RESTful API が同期モードでどのように機能するかを示しています。

例: RESTful API と JSON を使用した魔方陣の同期実行
この例では、MATLAB を使用した実装、 JavaScript を使用した実装、Python を使用した実装の 3 つの別々の実装を示すことで、RESTful API と JSON を使用する方法を説明します。この例を実行すると、サーバーは 25 個のコンマ区切り値のリストを返します。これらの値は、列優先形式で表されている、デプロイされた MATLAB 関数 mymagic の出力です。myMagic 関数の MATLAB コードは次のとおりです。
function out = myMagic(in) out = magic(in); end
この例を実行するには、デプロイされた MATLAB 関数 myMagic が含まれている MATLAB Production Server インスタンスを実行する必要があります。デプロイ可能なアーカイブを作成する方法の詳細については、MATLAB Production Server 用のデプロイ可能なアーカイブの作成を参照してください。サーバーのセットアップの詳細については、コマンド ラインを使用したサーバー インスタンスの作成を参照してください。
HTTP リクエスト
POST /ctfArchiveName/myMagic HTTP/1.1
Host: localhost:9910
Content-Type: application/json
Content-Length: 77
{"rhs":[4,1],"nargout":1, "outputFormat":{"mode":"small","nanType":"string"}}MATLAB を使用したリクエストの実行
コード内の localhost は使用するホスト名、ctfArchiveName は使用するデプロイ可能なアーカイブ名、myMagic は使用する関数名に置き換えます。コードを保存して、MATLAB で実行します。サーバーは myMagic 関数の出力を返します。
url = 'http://localhost:9910/ctfArchiveName/myMagic'; payload = mps.json.encoderequest({[5]}); options = weboptions; options.ContentType = 'text'; options.MediaType = 'application/json'; response = webwrite(url, payload, options); result = mps.json.decoderesponse(response); result{1}
JavaScript を使用したリクエストの実行
Node.js® を使用して、この RESTful API の JavaScript 実装を実行できます。コード内の localhost は使用するホスト名、ctfArchiveName は使用するデプロイ可能なアーカイブ名、myMagic は使用する関数名に置き換えます。以下のコードを、拡張子 .js をもつファイルとして保存して、Node.js で実行します。サーバーは myMagic 関数の出力を返します。
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify({
"rhs": [4,1],
"nargout": 1,
"outputFormat": {"mode": "small","nanType": "string"}
});
const requestOptions = {method: "POST", headers: myHeaders, body: raw, redirect: "follow"};
fetch("http://localhost:9910/ctfArchiveName/myMagic", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
Python を使用したリクエストの実行
次のコードは、任意の Python 環境で実行できます。コード内の URL の CTF アーカイブと関数の名前は、使用するものに合わせて変更します。既定では、アーカイブ名は ctfArchiveName、関数は myMagic です。このコードは、サーバー上で実行されている myMagic 関数の出力を返します。
import requests
import json
url = "http://localhost:9910/ctfArchiveName/myMagic"
payload = json.dumps({
"rhs": [4,1],
"nargout": 1,
"outputFormat": {"mode": "small","nanType": "string"}
})
headers = {'Content-Type': 'application/json'}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)MATLAB 関数を MATLAB Production Server にデプロイし、RESTful API と JSON を使用して呼び出すエンドツーエンドのワークフロー例については、RESTful API、JSON、および JavaScript を使用した Web ベース ツールの作成を参照してください。
非同期実行
非同期モードでは、クライアントは複数のリクエストを POST 送信でき、いずれの場合もサーバーは、新しいリソースを作成して各リクエストに対応する一意の URI を返すことでレスポンスします。この URI はレスポンスメッセージの本文内にカプセル化されます。クライアントは、サーバーが返す URI をクエリや結果の取得などに使用できます。
次の表は、非同期モードの RESTful API 呼び出しの一覧です。
| 呼び出し | 目的 |
|---|---|
| POST Asynchronous Request | サーバーに対して非同期リクエストを行う |
| GET Representation of Asynchronous Request | サーバーに対して行われた非同期リクエストがどのように表されるかを表示する |
| GET Collection of Requests | リクエストのコレクションを表示する |
| GET State Information | リクエストの状態情報を取得する |
| GET Result of Request | リクエストの結果を取得する |
| POST Cancel Request | リクエストをキャンセルする |
| DELETE Request | リクエストを削除する |
次の図は、RESTful API が非同期モードでどのように機能するかを示しています。この図は、すべての RESTful API 呼び出しに対応しているわけではありません。呼び出しの完全なリストについては、上記の表を参照してください。

例: RESTful API と JSON を使用した魔方陣の非同期実行
この例では、JavaScript を使用した非同期実装に RESTful API と JSON を使用する方法を説明します。この例を実行すると、サーバーは 100 個のコンマ区切り値のリストを返します。これらの値は、列優先形式で表されている、デプロイされた MATLAB 関数 myMagic の出力です。mymagic 関数の MATLAB コードは次のとおりです。
function out = myMagic(in) out = magic(in); end
この例を実行するには、デプロイされた MATLAB 関数 myMagic が含まれている MATLAB Production Server インスタンスを実行する必要があります。デプロイ可能なアーカイブを作成する方法の詳細については、MATLAB Production Server 用のデプロイ可能なアーカイブの作成を参照してください。サーバーのセットアップの詳細については、コマンド ラインを使用したサーバー インスタンスの作成を参照してください。
サンプルの JavaScript コードを次に示します。
<!DOCTYPE html>
<html>
<head>
<title>Magic Square</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
// MPS RESTful API (Asynchronous): Specify URL
var hostname = "http://localhost:9910";
var mode = "async";
var clientID = "client100";
var ctfName = "myMagic";
var matlabFuncName = "myMagic"
var url = hostname + "/" + ctfName + "/" + matlabFuncName + "?mode=" + mode + "&client=" + clientID;
// Specify arguments
var params = {
"nargout": 1,
"rhs": [100],
"outputFormat": {"mode": "small"}
};
$.ajax(url, {
data: JSON.stringify(params),
//MPS RESTful API (Asynchronous): Specify Content-Type to application/json and Specify HTTP POST method
contentType: 'application/json',
method: 'POST',
dataType: 'json',
success: function(response) {
// Print Request URI to webpage
$("#requestURI").html('<strong>Request URI: </strong>' + hostname + response.self);
pollUsingUp(response);
}
});
// Polling Server using UP
function pollUsingUp(request) {
setTimeout(function() {
var newSeq = parseInt(request.lastModifiedSeq) + 1;
var queryURI = hostname + request.up + "?since=" + newSeq + "&ids=" + request.id;
$.ajax({
url: queryURI,
method: 'GET',
dataType: 'json',
success: function(response) {
//Poll again if no data about the request was received.
if (response.data.length == 0) {
pollUsingUp(request);
return;
}
var requestResource = response.data[0];
// Print "state" of request
$("#state").html('<strong>State: </strong>' + requestResource.state);
if (requestResource.state != "READY" && requestResource.state != "ERROR") {
//Keep polling if the request is not done yet.
pollUsingUp(requestResource);
} else {
var requestURI = hostname + requestResource.self;
var responseURI = hostname + requestResource.self + "/result";
// Get result.
$.ajax({
url: responseURI,
// MPS RESTful API (Asynchronous): Specify HTTP GET method
method: 'GET',
dataType: 'json',
success: function(response) {
if (response.hasOwnProperty("lhs")) {
$("#demo").html('<p>' +
response.lhs[0] + '</p>');
//Uncomment the next line if using JSON large representation
//response.lhs[0].mwdata + '</p>');
} else if (response.hasOwnProperty("error")) {
alert("Error: " + response.error.message);
}
// MPS RESTful API (Asynchronous): Specify HTTP DELETE method
$.ajax({
url: requestURI,
method: 'DELETE'
});
}
});
}
}
});
}, 200);
}
</script>
</head>
<body>
<p><strong>MPS RESTful API and JSON EXAMPLE</strong></p>
<p> >> myMagic(5)</p>
<p id="requestURI"></p>
<p id="state"></p>
<p id="demo"></p>
<p> # output from server returned in column-major format </p>
</body>
</html>HTTP クッキーの管理
Azure® での MATLAB Production Server のデプロイでは、サーバーにデプロイされた MATLAB 関数を呼び出すために HTTPS エンドポイント URL が提供されます。Azure アプリケーション ゲートウェイは、クッキーを使用することで同じサーバー上にユーザー セッションを維持する、クッキーベースのセッション アフィニティを提供します。クライアント プログラムからリクエストを受信すると、アプリケーション ゲートウェイは Set-Cookie HTTP レスポンスヘッダーに、リクエストを処理するバーチャル マシン (VM) に関する情報を設定します。
非同期リクエストの実行
非同期リクエストを使用して、サーバーにデプロイされた MATLAB 関数を実行するクライアント プログラムは、後続のすべてのリクエストにおいて Cookie HTTP リクエスト ヘッダーに Set-Cookie ヘッダーの値を設定する必要があります。これにより、最初のリクエストを処理するのと同じサーバー VM が、そのセッションの後続のすべてのリクエストを処理するようになります。
同期リクエストの実行
同期リクエストを使用して、サーバーにデプロイされた MATLAB 関数を実行するクライアント プログラムは、Cookie HTTP リクエスト ヘッダーに Set-Cookie ヘッダーの値を設定してはならず、Cookie の値が以前に設定されている場合は、それをクリアする必要があります。これにより、同期リクエストが負荷分散されて、同じサーバー VM によって処理されないようにします。