Skip navigation links

Package com.mathworks.mps.client.rest

RESTful API and Protocol Buffer Support

See: Description

Package com.mathworks.mps.client.rest Description

RESTful API and Protocol Buffer Support

The MATLAB® Production Server™ Java™ client API offers two workflows for client-server communication.

One workflow that uses the MWHttpClient hides the implementation details of request creation, data serialization and deserialization in both asynchronous and synchronous requests sent to the server. For more information, see overview.

The other workflow provides you the flexibility to use your own HTTP client for client-server communication. This workflow relies on the MATLAB Production Server RESTful API. Starting in R2020a, the RESTful API supports protocol buffers (protobuf) for data serialization in the Java client API. Protocol buffers are a language-neutral and platform-neutral method of serializing structured data. To use protocol buffers, set the HTTP Content-Type header to application/x-google-protobuf. The Java client API internally creates protocol buffer messages based on a proto format and returns the corresponding byte array. Use this byte array in the HTTP request body. The Java client API provides methods and classes to deserialize the protocol buffer responses.

The examples that follow explain how to make asynchronous and synchronous requests to the server and the support for MATLAB structures (structs) in the second workflow. You use the java.net package for making HTTP requests to evaluate a MATLAB function mymagic deployed on a MATLAB Production Server instance running on localhost:9910. To use the Java client API, you must include mps_client.jar in the CLASSPATH. Find mps_client.jar in $MPS_INSTALL/client/java, where $MPS_INSTALL is the location in which MATLAB Production Server is installed.

Sample code for the examples is available in $MPS_INSTALL/client/java/examples/MagicSquare.

Asynchronous RESTful Requests using Protocol Buffers

1. Make an asynchronous request to the server

2. Get the state information of the request

3. View the collection of requests owned by a particular client

4. Retrieve the results of a request

1. Make an asynchronous request to the server

Use the POST Asynchronous Request RESTful API to make the initial request to the server.

            String clientId = "123";
            String mpsBaseUrl = "http://localhost:9910";
            URL url;
            url = new URL(mpsBaseUrl + "/mymagic/mymagic?mode=async&client="+clientId);
            final static protected String CONTENT_TYPE = "application/x-google-protobuf";
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);

    
            MATLABParams mlMakeBody = MATLABParams.newInstance(1, double[][].class, 2);
            OutputStream output = urlConnection.getOutputStream();
            output.write(mlMakeBody.getRequestBody());
            output.flush();
    
            MATLABRequestHandle mlInitialResponse = MATLABRequestHandle.newInstance(urlConnection.getInputStream());
            System.out.println("First Request has been Sent. Initial response is below");
            System.out.println("State: "+ mlInitialResponse.getState() + " " + "Request URL: "+mlInitialResponse.getRequestURL() + " Last modified sequence: " + mlInitialResponse.getLastModifiedSeq());

    

2. Get the state information of the request.

Use the GET State Information RESTful API to get the state of the request. In the request URL, set the query parameter format to protobuf so that the server to return the output in protocol buffer format. Parse the response to get the state of the request and the current lastModifiedSeq value at the server. Use the methods defined in the MATLABRequest class to parse the response.

            url = new URL(mpsBaseUrl + mlInitialResponse.getRequestURL() + "/info?" + "format=protobuf");
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            MATLABRequest requestInfoTmp = MATLABRequest.newInstance(urlConnection.getInputStream());
            System.out.println(requestInfoTmp.getState() + " " + requestInfoTmp.getLastModifiedSeq());

    

3. View the collection of requests owned by a particular client.

Use the GET Collection of Requests RESTful API to view the collection of requests sent by a particular client represented by clientId. In the request URL, set the query parameter format to protobuf so that the server returns the output in protocol buffer format. Use the MATLABRequests class newInstance method to parse the response body of a successful request. MATLABRequests class has a getMATLABRequests method that returns a Map of requestURL and MATLABRequest object.

            url = new URL(mpsBaseUrl + mlInitialResponse.getInstanceId() + "requests" + "?since="
                + mlInitialResponse.getLastModifiedSeq() + "&format=protobuf&" + "clients=" + clientId);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            MATLABRequests updates = MATLABRequests.newInstance(urlConnection.getInputStream());

            Map<String, MATLABRequest> urlUpdates = updates.getMATLABRequests();
            System.out.println("State of the Requests with the client: " + clientId);
            for (String requestURL : urlUpdates.keySet()) {
                System.out.println(requestURL + ":" + urlUpdates.get(requestURL).getState());
            }

    

4. Retrieve the results of a request.

Use the GET Result of Request RESTful API to fetch the request results after the request state has changed to READY. Use the methods defined in the MATLABResult class to parse the response. Create a MATLABResult object using the MATLABParams object created in Step 1.2 and the response body of the GET Result of Request request. Write a helper method printResult which takes the result that is parsed from the response body as input and prints the corresponding 2-D array.

If an error occurs when the deployed MATLAB function executes, then the call to the getResult method throws a MATLABException that contains the error message from MATLAB. Even in this case , the state of the request is still READY as the function call was successful while the function execution resulted in an error.

If the request state is ERROR, use the HTTPErrorInfo class instead of MATLABResult class to parse the response. Use the methods defined in the HTTPErrorInfo class to get information about the error.

            url = new URL(mpsBaseUrl + mlInitialResponse.getRequestURL() + "/result?" + "format=protobuf");
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            if (requestInfoTmp.compareTo(MATLABRequestState.ERROR_STATE) == 0) {
                HTTPErrorInfo httpErrorInfo = HTTPErrorInfo.newInstance(urlConnection.getInputStream());
                System.out.println("ErrorCode: " + httpErrorInfo.getHttpErrorCode());
                System.out.println("Error Message: " + httpErrorInfo.getHttpErrorMessage());
                System.out.println("Error body: " + httpErrorInfo.getHttpBody());
            }else{

                MATLABResult<double[][]> mlFinalResult1 = MATLABResult.newInstance(mlMakeBody, urlConnection.getInputStream());
                try{
                    double[][] magicSq1 = mlFinalResult1.getResult();
                    printResult(magicSq1);
                }catch(MATLABException e){
                    e.printStackTrace();
                }

                private static void printResult(double[][] result) {
                    for (double[] row : result) {
                        for (double element : row) {
                            System.out.print(element + " ");
                        }
                        System.out.println();
                    }
                }
            }

    

Synchronous RESTful Requests using Protocol Buffers

Use the POST Synchronous Request RESTful API to make the initial request to the server.

            URL url;
            url = new URL(mpsBaseUrl + "/mymagic/mymagic");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", CONTENT_TYPE);
    
            MATLABParams mlMakeBody = MATLABParams.newInstance(1, double[][].class, 2);
            OutputStream output = urlConnection.getOutputStream();
            output.write(mlMakeBody.getRequestBody());
            output.flush();
    

            MATLABResult<double[][]> mlFinalResult1 = MATLABResult.newInstance(mlMakeBody, urlConnection.getInputStream());
            try{
                double[][] magicSq1 = mlFinalResult1.getResult();
                printResult(magicSq1);
            }catch(MATLABException e){
                e.printStackTrace();
            }

            private static void printResult(double[][] result) {
                for (double[] row : result) {
                    for (double element : row) {
                        System.out.print(element + " ");
                    }
                    System.out.println();
                }
            }

    

Struct Support for RESTful Request using Protocol Buffers

The Java client API also supports sending structs represented as Java objects as input during the evaluation of a MATLAB function deployed on the server. When you make the initial POST request to send data, extend the MWDefaultMarshalingRules interface to implement a new set of marshaling rules for the list of classes being marshaled.

Skip navigation links

Copyright 2010-2016 The MathWorks, Inc.