RESTful API for MATLAB Function Execution
The MATLAB® Production Server™ RESTful API for MATLAB function execution enables you to evaluate MATLAB functions on remote servers using JSON representation of MATLAB data types and protocol buffers. Protocol buffer support is available only in the Java® and .NET client APIs.
You can write client code that uses the MATLAB Production Server RESTful API in web-based languages such as JavaScript® and embed it in HTML pages. You can then use these web pages to send requests and retrieve responses from a MATLAB Production Server instance. While web-based applications may be more amenable to client code written in JavaScript, you can use any HTTP supported programming language such Java, Python, C++, .NET, and many others to develop client applications.
If client programs make requests from different domains, programmers using JavaScript must verify whether Cross-Origin Resource Sharing (CORS) is enabled on the
server. To enable CORS on the server, the server administrator must set the appropriate
value for the cors-allowed-origins property in the
main_config
server configuration file.
Characteristics of RESTful API
The RESTful API for MATLAB function execution uses the HTTP request-response model for communication with MATLAB Production Server. This model includes request methods, response codes, message headers, and message bodies. The RESTful API has the following characteristics:
The HTTP methods—POST, GET, and DELETE—form the primary mode of communication between client and server.
Unique Uniform Resource Identifiers (URIs) identify the resources that the server creates.
Message headers convey metadata such as the Content-Type of a request.
The API supports
application/json
as the HTTPContent-Type
header.The RESTful API for MATLAB function execution also supports
application/x-google-protobuf
as the HTTPContent-Type
through the Java and .NET client APIs only.
The message body of the request contains information to be sent to the server.
If you use JSON as the data serialization format, inputs to the MATLAB function contained within a deployed archive are represented in JSON and encapsulated within the body of a message. For more information, see JSON Representation of MATLAB Data Types.
If you use protocol buffers (protobuf) for data serialization, the Java and .NET client libraries provide helper classes to internally create protobuf messages based on a proto format and return the corresponding byte array. Use this byte array in the message body of the request.
The message body of the response contains information about a request such as state or results.
If you use protobuf for data serialization, the Java and .NET client libraries provide methods and classes to deserialize the protobuf responses.
The API supports both the synchronous and asynchronous modes of the server.
Note
The examples and graphics that follow use JSON as the data serialization format.
Synchronous Execution
In synchronous mode, after a client posts a request, the worker process of the server blocks all further requests until it has completed processing the original request. After processing is complete, the worker automatically returns a response to the client. Since it is the worker that blocks during request processing, if there are other workers available, the server can accept other synchronous requests for processing. To make a synchronous request to the server and wait for a response, use POST Synchronous Request.
The following graphic illustrates how the RESTful API works in synchronous mode.
Example: Synchronous Execution of Magic Square Using RESTful API and JSON
This example shows how to use the RESTful API and JSON by providing three separate
implementations—one using MATLAB, one using
JavaScript
and one using
Python®. When you execute this example, the server returns a list
of 25 comma-separated values. These values are the output of the deployed
MATLAB function mymagic
, represented in column-major
format. The MATLAB code for the myMagic
function follows.
function out = myMagic(in) out = magic(in); end
For this example to run, a MATLAB
Production Server instance containing the deployed MATLAB function myMagic
needs to be running. For more
information on how to create a deployable archive, see Create Deployable Archive for MATLAB Production Server. For more information on setting up a server, see Create Server Instance Using Command Line.
HTTP Request
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"}}
Use MATLAB to Make a Request
In the code, replace localhost
with your hostname,
ctfArchiveName
with the name of your deployable archive
and myMagic
with the name of your function. Save the code and
run it in MATLAB. The server returns the output of the myMagic
function.
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}
Use JavaScript to Make a Request
You can run this JavaScript implementation of the RESTful API using Node.js®. In the code, replace localhost
with your
hostname, ctfArchiveName
with the name of your deployable
archive and myMagic
with the name of your function. Save the
code below as a file with the extension .js
and run it with
Node.js. The server returns the output of the myMagic
function.
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));
Use Python to Make a Request
You can run the following code in the Python environment of your choice. In the code, change the name of the
CTF archive and function in the URL to match yours. By default, the archive name
is ctfArchiveName
and the function is
myMagic
. The code returns the output of the
myMagic
function running on the
server.
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)
For an end-to-end workflow example of deploying a MATLAB function to MATLAB Production Server and invoking it using RESTful API and JSON, see Create Web-Based Tool Using RESTful API, JSON, and JavaScript.
Asynchronous Execution
In asynchronous mode, a client is able to post multiple requests, and in each case the server responds by creating a new resource and returning a unique URI corresponding to each request. The URI is encapsulated within the body of the response message. The client can use the URI that the server returns for querying and retrieving results among other uses.
The RESTful API calls for asynchronous mode are listed in the following table:
Call | Purpose |
---|---|
POST Asynchronous Request | Make an asynchronous request to the server |
GET Representation of Asynchronous Request | View how an asynchronous request made to the server is represented |
GET Collection of Requests | View a collection of requests |
GET State Information | Get state information of a request |
GET Result of Request | Retrieve the results of a request |
POST Cancel Request | Cancel a request |
DELETE Request | Delete a request |
The following graphic illustrates how the RESTful API works in asynchronous mode. The graphic does not cover all the RESTful API calls. For a complete list of calls, see the preceding table.
Example: Asynchronous Execution of Magic Square Using RESTful API and JSON
This example shows how to use the RESTful API and JSON for asynchronous execution
using JavaScript. When you execute this example, the server returns a list of 100
comma-separated values. These values are the output of the deployed MATLAB function myMagic
, represented in column-major
format. The MATLAB code for the mymagic
function follows.
function out = myMagic(in) out = magic(in); end
For this example to run, a MATLAB
Production Server instance containing the deployed MATLAB function myMagic
needs to be running. For more
information on how to create a deployable archive, see Create Deployable Archive for MATLAB Production Server. For more information on setting up a server, see
Create Server Instance Using Command Line.
Sample JavaScript code follows.
<!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>
Manage HTTP Cookie
A MATLAB
Production Server deployment on Azure® provides an HTTPS endpoint URL to invoke MATLAB functions deployed to the server. The Azure application gateway provides cookie-based session affinity, where it
uses cookies to keep a user session on the same server. On receiving a request from
a client program, the application gateway sets the Set-Cookie
HTTP response header with information about the server virtual machine (VM) that
processes the request.
Asynchronous Request Execution
A client program that uses asynchronous requests to execute a MATLAB function deployed to the server must set the
Cookie
HTTP request header with the value of the
Set-Cookie
header for all subsequent requests. This
ensures that same server VM that processes the first request processes all
subsequent requests for that session.
Synchronous Request Execution
A client program that uses synchronous requests to execute a MATLAB function deployed to the server must not set the
Cookie
HTTP request header with the value of the
Set-Cookie
header, and must clear the value of the
Cookie
header if it has been previously set. This ensures
that the synchronous requests are load balanced and the same server VM does not
process them.
For more information about the architecture and resources for MATLAB Production Server on Azure, see Architecture and Resources on Azure and Architecture and Resources on Azure.