9.3. Ajax StubDelegate, Facade, Procedure, Proxy, Remote, Remoting, RPC Figure 9-3. Ajax Stub9.3.1. Developer StoryDevi begins working on the browser script for a trading application and soon decides she needs a way to execute a trade. There's already a method to do that on the backend TRadeManager object, so after 15 seconds reconfiguring the Ajax Stub, the browser script is able to invoke the method. 9.3.2. ProblemHow do you implement an RPC Service (see earlier in this chapter)? 9.3.3. Forces
9.3.4. SolutionUse an Ajax Stub framework that allows browser scripts to directly invoke server-side operations, without having to worry about the details of XMLHttpRequest and HTTP transfer.. The aim is to let the JavaScript call remote operations as if they were regular JavaScript functions, facilitating a more natural program style. There are several frameworks to support stubbing of this nature. Typically, you declare which backend operations should be exposed, and the framework takes care of the remoting. It will provide a JavaScript stub object that will delegate the call over to the server side. For example, you might have a Java method like this: public class Book { public String getEdition(int year) {...} ... } After configuring an Ajax Stub framework for handling remoting, it's light work to make call the class from within the browser: editionLabel.innerHTML = book.getEdition( ); Typical facilities include:
A stubbing framework usually consists of two components:
9.3.5. Decisions9.3.5.1. How will you secure the server-side function?With great power comes great responsibility. An Ajax Stub makes it easy, bordering on trivial, to directly expose business operations. That means it's also easy to let curious users do things they shouldn't. Since many Ajax Apps push the whole user interface out to the browser, the web tier is left publishing business methods. Harry Fuecks, author of the Ajax Stub toolkit JPSpan (http://jpspan.sourceforge.net/), gave this cautionary example on the Ajax Blog (http://ajaxblog.com/archives/2005/05/25/a-grumpier-ajaxian). A naïve export of a business operation could end up with a call like this: var ccNum = AJAX.getCreditCardNumber(userId); Anyone can edit the JavaScript and pass any argument to the credit card operation. Another stubbing framework, DWR (http://getahead.ltd.uk/dwr/getstarted), warns: "There is a danger that you could cause all sorts of security problems using this code. You need to think about security earlier rather than later." Other approaches, such as RESTful Service, are also vulnerable to the same threat, but they tend to encourage more analysis, because you have to explicitly design the service interface. With Ajax Stub, you're effectively ticking a few boxes to say which backend operations can be executed. A few guidelines:
9.3.6. Real-World ExamplesThese examples cover available frameworks for creating Ajax Stubs. 9.3.6.1. SAJAX frameworkSAJAX (http://www.modernmethod.com/sajax/) is an Ajax Stub framework that actually supports multiple backend languages. The browser side is the same for all, but there are different server-side proxy components depending on which language is used. Among the backend languages are ASP, ColdFusion, Perl, PHP, Python, and Ruby. 9.3.6.2. DWR frameworkDWR (http://getahead.ltd.uk/dwr/overview/dwr) is an open source framework for Ajax Stubs to Java classes. On the server side, you run a DWR servlet and configure it with a separate XML file. In the browser, just include a JavaScript file. Java and JavaScript may not have much in common, but calls do at least look the same. A DWR JavaScript-to-Java call looks just like a Java-to-Java call. 9.3.6.3. CL-AJAX frameworkRichard Newman's open source CL-AJAX (http://www.cliki.net/cl-ajax) supports stubbing of Common Lisp functions. 9.3.7. Code Refactoring: AjaxPatterns SAJAX SumIn this refactoring illustration, the Basic Sum Demo (http://ajaxify.com/run/sum) is refactored to use an Ajax Stub (http://ajaxify.com/run/sum/stub), based on SAJAX (http://www.modernmethod.com/sajax/). To begin with, we do away with the old Sum service (sum.phtml) and create a standalone, backend, calculator module. Now that we're using an RPC approach, we'll call the operation add instead of sum, to make it distinctly a verb. So calculator.phtml looks like this: <? function add($figure1, $figure2, $figure3) { echo $figure1 + $figure2 + $figure3; } ?> With the stub, we can allow the browser-side script to directly invoke that function. The JavaScript call looks like this: function submitSum( ) { x_add($("figure1").value,$("figure2").value,$("figure3").value,onSumResponse); } Here's how you set up the SAJAX glue between the JavaScript x_add and the PHP add. In PHP, we tell SAJAX which functions are exported: <? require_once("Sajax.php"); ?> ... sajax_init( ); sajax_export("add"); sajax_handle_client_request( ); And in outputting the script, some PHP code generates the required JavaScriptin this case, the x_add( ) function, which will forward on to SAJAX on the server side and eventually interpret its response: <script> <? sajax_show_javascript( ); ?> </script> 9.3.8. Alternatives9.3.8.1. XMLHttpRequest CallAjax Stubs are built on top of XMLHttpRequest Calls (Chapter 6) and represent a different approach to the usual Ajax remoting. XMLHttpRequest Calls leave the user to deal directly with HTTP concepts and packing and unpacking of messages, tasks that Ajax Stubs take care of. The benefit of direct XMLHttpRequest Calls is that the server-side service interface is independent of the underlying implementation. 9.3.8.2. XML-RPC and SOAPXML-RPC and SOAP are more generic (non-Ajax-specific) ways to develop RPC Services (see earlier in this chapter). Since Ajax Stubs tend to produce Ajax-specific services, XML-RPC or SOAP might be more appropriate if you're opening up to external clients. 9.3.9. Related Patterns9.3.9.1. RPC ServiceAn Ajax Stub is one way to implement an RPC Service. 9.3.9.2. JSON MessageJSON Messages (see later in this chapter) are being used by several Ajax Stub frameworks because Ajax Stubs need to share data between browser and server; i.e., inbound arguments and outbound return values. These objects should be standard JavaScript objects in the browser and standard Java or PHP or whatever-your-language-choice objects on the server. In between, it's most convenient to transfer them as strings. JSON defines a standard way to convert objects in many languages to and from a string representation. An even more ambitious standard is JSON-RPC (http://json-rpc.org/), a protocol for remoting that's touted as a lightweight alternative to XML-RPC. There's an Ajax Stub framework based on JSON-RPC, the aptly named JSON-RPC-Java (http://oss.metaparadigm.com/jsonrpc/). |