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 two separate
implementations—one using
JavaScript
and the other 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.
JavaScript Implementation
With the JavaScript implementation of the RESTful API, you include the script within
the <script> </script>
tags of an HTML page. When
you open this HTML page in a web browser, the server returns the values of the
mymagic
function. Note that the server needs to have
CORS
enabled for JavaScript code to work. For more information on how to enable
CORS
, see cors-allowed-origins.
A sample HTML code with embedded JavaScript follows.
<!DOCTYPE html> <html> <head> <title>Magic Square</title> <script> var request = new XMLHttpRequest(); //MPS RESTful API: Specify URL var url = "http://localhost:9910/ctfArchiveName/mymagic"; //MPS RESTful API: Specify HTTP POST method request.open("POST",url); //MPS RESTful API: Specify Content-Type to application/json request.setRequestHeader("Content-Type", "application/json"); var params = { "nargout": 1, "rhs": [5] }; request.send(JSON.stringify(params)); request.onreadystatechange = function() { if(request.readyState == 4) { //MPS RESTful API: Check for HTTP Status Code 200 if(request.status == 200) { result = JSON.parse(request.responseText); if(result.hasOwnProperty("lhs")) { //MPS RESTful API: Index into "lhs" to retrieve response from server document.getElementById("demo").innerHTML = '<p>' + result.lhs[0].mwdata; } } else if(result.hasOwnProperty("error")) { alert("Error: " + result.error.message); } } }; </script> </head> <body> <p>MPS RESTful API and JSON EXAMPLE</p> <p> >> mymagic(5)</p> <p id="demo"></p> <p> # output from server returned in column-major format </p> </body> </html>
Python Implementation
import json import http.client conn = http.client.HTTPConnection("localhost:9910") headers = { "Content-Type": "application/json"} body = json.dumps({"nargout": 1, "rhs" : [5]}) conn.request("POST", "/mymagic/mymagic", body, headers) response = conn.getresponse() if response.status == 200: result = json.loads(response.read()) if "lhs" in result: print("Result of magic(5) is " + str(result["lhs"][0]["mwdata"])) elif "error" in result: print("Error: " + str(result["error"]["message"]))
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.
A sample HTML code with embedded JavaScript 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.