AJAX and REST

The following introduction shows how the Barracuda server is used in designing AJAX and RESTful web-services.

See also Online AJAX examples and AJAX Over WebSockets (GitHub).

AJAX

An Ajax web application retrieves data from the server asynchronously in the background without interfering with the display and behavior of the existing page. Ajax applications are typically designed for enhancing standard web-applications and are designed to gracefully degrade to a standard web application when the browser does not support JavaScript or if JavaScript is disabled.

In the following example, a basic calculator is designed as a standard web application, and we will later enhance this calculator by using Ajax. To keep it simple, the calculator will be designed to add two numbers only.

<?lsp

   local var1
   local var2
   local result = ""
   
   -- Fetch all URL encoded (POST'ed form) data sent from client as a Lua table.
   local d = request:data()
   if d.var1 and d.var2 then -- If client sends data
      -- Convert URL encoded data to numbers
      var1 = tonumber(d.var1)
      var2 = tonumber(d.var2)
      -- var1 and/or var2 are nil if data could not be converted to a number.
      -- Set result = var1+var2 if var1 and var2 are OK, otherwise set result to
      -- "???"
      result = var1 and var2 and (var1+var2) or "???"
   end
   -- Else, a standard browser GET
   
?>
<html>
  <head>
    <title>Addition</title>
  </head>
  <body>
    <form method="post">
      <input type="text" name="var1" value="<?lsp=var1 or ""?>"/>
      +
      <input type="text" name="var2" value="<?lsp=var2 or ""?>"/>
      = <span id="result"><?lsp=result?></span>
      <br/>
      <input type="submit" value="Submit"/>
    </form>
  </body>
</html>

The html form starts on line 26 and ends on line 33. The user enters a number into the two text fields (line 27 and 29). The data is sent as URL encoded data to the server when the user presses the submit button on line 32. The URL-encoded data for the above form is sent as: var1=10&var2=11, where 10 and 11 are numbers entered into the text fields.

Lua script code starting on line 1 and ending on line 20 is executed by the server every time the browser sends a request to the LSP page. If the browser sends the two URL-encoded variables var1 and var2, line 9 to 17 in the above code is executed on the server. The server side code extracts the variables and converts the variables to numbers.

The "result" is dynamically inserted into the generated HTML on line 30. We also update the value attributes on line 27 and 29. Updating the value fields make the input variables persistent -- i.e. the HTML code returned in response to a "browser POST request" have the text fields set to the previous value.

Lets's go ahead and enhance the web-application using Ajax, but at the same time, make sure the application still works when JavaScript is disabled in the browser.

<?lsp
 
local var1
   local var2
   local result = ""
    
   -- Fetch all URL encoded (POST'ed form) data sent from the browser.
   -- The data, if any, is returned as a Lua table.
   local d = request:data()
   if d.var1 and d.var2 then -- If browser sent data to server
      -- Convert URL encoded data (strings) to numbers
      var1 = tonumber(d.var1)
      var2 = tonumber(d.var2)
      -- var1 and/or var2 are nil if data could not be converted to a number.
      -- Set result = var1+var2 if var1 and var2 are OK,
      -- otherwise set result to "???"
      result = var1 and var2 and (var1+var2) or "???"
    
      -- Is this a standard POST or is this an AJAX call?
      if "XMLHttpRequest" == request:header"x-requested-with" then
         -- YES, AJAX call.
         response:json{result=result}
         return -- We are done.
      end
      -- Fall through if not AJAX call, i.e. if standard POST.
   end
   -- Else, a standard browser GET
    
?>
<html>
  <head>
    <script type="text/javascript" src="/rtl/jquery.js"></script>
    <script type="text/javascript">
    
   /* Extract the two elements var1 and var2 from the html form and send
    * the data to server.
    */
   function sendAJAX()
   {
      // The data sent to the server looks like a standard browser POST message.
      var urlEncData = {
         var1:$("input[name='var1']").val(), // var1 = value of html input var1
         var2:$("input[name='var2']").val()
      };
      /* The AJAX call. Note that we use an anonymous function for the
       * asynchronous response.
       */
      $.getJSON(location.href , urlEncData, function(json) {
         /* This asynchronous callback function is triggered when the
          * server sends the JSON response data. Convert the 'result'
          * number to a string and set the data for the html span
          * element.
          */
         $("#result").html(json.result+"");
      });
   };
    
   /* Called when user clicks the submit button.
    */
   function submit()
   {
      sendAJAX();
      // Prevents browser from sending a standard POST request to the server.
      return false;
   };
    
    
   $(function() {
      // Bind the submit function to the html form "submit" button.
      $("input[type='submit']").click(submit);
      /* Bind the sendAJAX function to the change and keyup elements in
       * the form. This creates a realtime update of the "result" value
       * -- i.e. AJAX calls are issued for each change of the input
       * elements.
       */
      $("input[type='text']").change(sendAJAX).keyup(sendAJAX);
   });
    </script>
  </head>
  <body>
    <form method="post">
      <input type="text" name="var1" value="<?lsp=var1 and var1 or ""?>"/>
      +
      <input type="text" name="var2" value="<?lsp=var2 and var2 or ""?>"/>
      = <span id="result"><?lsp=result?></span>
      <br/>
      <input type="submit" value="Submit"/>
    </form>
  </body>
</html>

If you take a look at the above code, you will see that we have not changed the original code, but we have added additional code. The new Lua code starts on line 20 and ends on line 24. The bulk of the new code is the added JavaScript code that is executed by the browser as soon as the page is loaded. The code starts on line 32 and ends on line 78.

It is common to send Ajax data from the browser to the client as URL-encoded data. The server side code for extracting the URL-encoded data and calculating the result (line 12-17) can therefore be used as it was in the original page. The new Lua code starting on line 20 checks if the request is from an Ajax call. If it is, the result is assembled into a Lua table, converted to JSON, and sent to the browser.

The JavaScript code starting on line 48 uses the JQuery function $.getJSON for sending the XMLHttpRequest to the server. The second parameter to $.getJSON is a JavaScript table that automatically converts to URL-encoded data by $.getJSON. The asynchronous callback function extracts the JSON encoded data sent from the server and updates the display with the result.

Notice how we extract data from the text fields on line 42 and 43 by using JQuery selectors. We use the data to create a JavaScript table that is sent as URL-encoded data to the server.

The code starting on line 68 uses the JQuery ready event to automatically execute the code at startup when the page is loaded by the browser.

We use JQuery selectors on line 76 to bind event functions to the two text input fields. The change event is fired every time the fields are changed and the keyup is fired when the keybord key is released. We bind a click event to the submit button on line 70. The submit function returns false after the Ajax call is activated, thus preventing the browser from sending the form data to the server. Binding the click event function to the submit button will not work if JavaScript is disabled and the form gracefully degrades to a standard web-form.

RESTful Web-Services

RESTful web-services can easily be designed using the directory type. The getting started guide includes an example of how one can create RESTful web-services and use logical URL's.