thinking in rules

InRule for Web and Mobile

Calling irServer from JavaScript

Jim Wray | 1/14/2015

One of the goals of the InRule v4.6 release was to make it easier for web and mobile developers to use InRule within their applications. A key feature of the release was the addition of a REST endpoint to the irServer Rule Execution Service. This makes it much easier to call InRule using basic JavaScript techniques. In this blog post we'll walk through a hello world example of calling the new endpoint from a simple web application.

Step 1: Create a Rule Application

For hello world examples in InRule, nothing beats a rectangle app. It takes no time to setup in irAuthor and provides a good way to get some rudimentary integration working. You create a new rule application, add two decimal fields for height and width and then a decimal calculation to multiply height by width.

 

 

 

 

 

 

 

At first we'll save this to the file system in an area accessible by the service but later I'll show you how to use ruleapps from irCatalog, as well. By default the rule execution service is set up to look in a RuleApps folder that is installed along with the service. On my machine it was installed to C:\Program Files (x86)\InRule\irServer\RuleEngineService\IisService\bin\RuleApps.

Step 2: Create the Web Form

To keep this example straightforward we will be hand-coding our HTML and JavaScript. Since this is a simple application, the HTML for our web form consists of three input fields and a button:

 

 

<body>
Height:
<input type="text" id="height"/>
<br />

Width:
<input type="text" id="width"/>
<br />

Area:
<input type="text" id="area" />

<input type="button" value="Click to run rules" onclick="callInRule();"/>
</body>

Step 3: Write the JavaScript

Now that the page is setup, let's move on to writing some JavaScript to call the rule engine. The first function we'll write will package up the data the user has entered and create a request object that we will post to the service. Note in the following code snippet that we have to stringify the state. Later we'll stringify the request object. When the server parses the request object it expects the state as a string and will parse that in a separate step. Also notice, that since we saved the rule application as a file all we need to specify is the rule application name.


        function getPostData() {

            var height = document.getElementById("height").value;
            var width = document.getElementById("width").value;

            var state = JSON.stringify({
                "Height": height,
                "Width": width
            });

            var postData = {
                "RuleApp": {
                    "FileName":"rectangleapp.ruleapp"
                },
                "EntityState": state,
                "EntityName": "Rectangle"
            };

            return postData;
        }

 

Next we create the callInRule() function that is called when the user clicks the button to run the rules. If you have ever made a web service call in JS, this code needs little, if any, explanation:


        function callInRule() {
            try
            {
                //The irServer Rule Execution Service REST endpoint URL
                var url = "http://localhost/InRuleRuleEngineService/HttpService.svc/ApplyRules";

                //The object to post to the service
                var postData = getPostData();

                //Typical JS service call
                var client = new XMLHttpRequest();
                client.open("POST", url, true);
                client.setRequestHeader("Content-Type", "application/json");
                client.setRequestHeader("Accept", "application/json");

                client.onreadystatechange = function () {
                    if (client.readyState == 4 && client.status == 200) {
                        writeOutput(client.responseText);
                    }
                }

                //Note that we stringify the post data
                client.send(JSON.stringify(postData));
            }
            catch (ex) {
                alert(ex.message);
            }
        }

 

Finally the last function we will write is called once the response is received. Here we take the response object and update the area field on the screen. Note that just like we had two stringify statements when building the request, now we have two parse statements. One to parse the response object and the other to parse the value of the state property. Once you have the state object in hand you simply bind to the UI manually or using your framework of choice.


        function writeOutput(response) {

            var ruleEngRespose = JSON.parse(response);
            var state = JSON.parse(ruleEngRespose.EntityState);

            document.getElementById("area").value = state.Area;
        }

 

Step 4: Use an irCatalog Ruleapp Instead

Requiring the copying of a file to the web server for deployment of rule changes might be fine for a POC but in a real application you are probably going to want to use a ruleapp from irCatalog. By modifying your getPostData() function as follows, you can make deployment as easy as checking into the catalog or promoting to your production irCatalog instance. 


        function getPostData() {

            var height = document.getElementById("height").value;
            var width = document.getElementById("width").value;

            var state = JSON.stringify({
                "Height": height,
                "Width": width
            });

            var postData = {
                "RuleApp": {
                    "RepositoryRuleAppRevisionSpec": {"RuleApplicationName": "RectangleApp"},
                    "RepositoryServiceUri": "http:\/\/localhost\/InRuleCatalogService\/service.svc"},
                "EntityState": state,
                "EntityName": "Rectangle"
            };

            return postData;
        }

 

The Future of InRule

The exciting implication of this example is that I no longer need to deploy any DLLs, write a web service wrapper or worry about the execution platform. Once the service is installed, InRule can be run anywhere HTML and JavaScript can run -- which is just about everywhere.

If you would like more examples like this on our blog please comment below and tell us what you would like to see next.


comments powered by Disqus