To allow your RIA applications to interact with server-side services, Flex provides RPC components. They are based on a service-oriented architecture (SOA), and enable your RIA application to connect SOAP (web services), REST (REpresentational State Transfer) or Java objects (remote object services). All of those three techniques use the HTTP protocol as the underlying transport protocol.
Remote services and asynchronous calls
In a Flex application, an RPC component sends data to a RPC service. Once the RPC service has finished the request processing, it returns its results data to the RPC component that made the request. In Flex, the RPC calls are asynchronous. That means the caller will not wait for the service to return and will continue its own execution. For example, while using asynchronous RPC, the following code is nonsense, as the getData method could take 10 seconds to execute, but the trace executes just after the call has been sent.
var serviceCallResult : Object = remoteService.getData(); trace("This message won't wait 10 seconds to be traced");
Services abstraction and BusinessDelegate
When using the Foundry, we recommend to create a BusinessDelegate instance, used to avoid direct interaction of the presentation tier with the remote services. One of the fundamental advantages is that changes on the remote services implementation will impact only the BusinessDelegate, not other components of the application. There are other advantages to use a service abstraction class :
- To achieve a particular task, an application sometimes need to perform more than one call, sometimes on more than one remote service. The aggregation of the calls should be performed in a service abstraction class.
- Two of the three RPC components (WebService, RemoteObject) are, for obvious reasons, dynamic classes. That means that, even if a method is not declared into the class, it can be called. It is a good idea to expose a “strong-typed” service abstraction class to the application, instead of a dynamic class.
- Moreover, when using HTTPService component, all calls are performed through a single send method. It is a good idea to expose a “strong-typed” service abstraction class to the application, instead of an object with a single method used to perform all remote calls.
Good practices on the service-side
Transfer and Value objects
Remote services provide, most of the time, coarse-grained methods that meet business requirements. Every method call made to the service is done through the network. Transport, serialization and processing of the calls may cause service overload and penalize the user experience. For example, the remote methods login and getUserProfile may have to be call subsequently.
The solution is to use TransferObject instances as cargos to transport multiple values in a single call. In our example, the method connectUser should return a LoginTO transfer object to aggregate the session data and user profile.
ValueObject is the former name of the TransferObject design pattern. For clarity reasons, the Foundry uses two separate designations :
- ValueObject as the basic type for values,
- TransferObject as the basic type for aggregators of value objects.
The connectUser method could return a LoginTO containing one instance of SessionVO and one of UserProfileVO.
AbstractTransferObject and AbstractValueObject classes are provided by the Foundry (ActionScript and Java classes, if applicable). We strongly recommend to use those classes when designing your service endpoints. The AbstractTransferObject class besides provides a header, that can be used to transport error codes and services messages to the client side.
RIA clients often need to call several methods to achieve a given process. Submit an order may be decomposed in the following steps :
- check the user credentials,
- check the billing data,
- submit the order to the database.
In a standard Web application, this process would certainly be achieved using 3 isolated transactions. In a RIA application, we would most probably achieve this process in 1single call to increase the user experience, so the service will have to expose the whole process in a single method of a single class.
A Facade is a component that hides service(s) complexity to the client. Whatever the RPC component you use to expose your services, we strongly encourage you to expose a well designed API to your rich client component. The BusinessDelegate created on the client-side should then have an interface similar to the service facade.
Handling service responses
As RPC components perform remote calls asynchronously, the Foundry provides a mechanism to handle service returns, base on the IBusinessResponder interface. Before calling the service, the BusinessDelegate links an object to a token (ACT stands for Asynchronous Completion Token) that enable the handling of remote call responses.
Using Observer pattern
Most of the times, Responder instances write data into one or several Model. The Model then have to broadcast so the views are updated. To do so, Model instances trigger notifications. The Observer mechanism is detailed in the diagram below.
First, the observers – commonly ViewHelper instances – register to the Model. When the business responder write into the Model, it triggers a notification to be handled by the observers.
If you want to see a concrete implementation of those practices and design patterns, please check the “Accessing Remote Services” tutorial.
- Introducing ActionScript Foundry
- Basic types and structures
- The collection packages
- The MVC Framework
- Remote procedure call
- Building localized Flex Applications
- Using SmartForm
- Using the FlexBrowser
- Full-text search tree
- ActionScript Foundry: a beginner’s guide
- Accessing Remote Services
- Developping a contact manager application (CManager) – Part 1