Macromedia Consulting
This is a user’s guide for the Flex Application Starter Toolkit (FAST) software toolkit that helps you develop Flex applications easier and faster. The toolkit is free and available for download through this article.
FAST addresses two fundamental aspects of Flex application development: event logging and data communications. To support event logging, FAST provides an API modeled after Java’s log4j and a Flex-based event display console. For data communications, FAST exposes a simplified programming interface that provides robust error handling, client-side data caching, diagnostic and performance information, and an underlying architecture that supports large applications and facilitates team development.
This toolkit embodies lessons learned from hands-on experience architecting and implementing over a dozen large scale, production-quality Rich Internet Applications. The toolkit was created by the Macromedia Consulting (MC) Team, whose purpose is to ensure the success of leading edge, large-scale Flex application development efforts. MC recognized a common set of problems that arose in nearly every project. Solving these problems required software design and implementation work that did not contribute directly to the functional requirements of the project; rather, the work done accomplished necessary “scaffolding” or infrastructure functionality. By packaging and distributing this toolkit, the MC team hopes to liberate others in the Flex development community from the need to recreate equivalent functionality on other projects.
To complete this tutorial you will need to install the following software and files:
The download includes the following:
The FAST toolkit
FAST example applications
FAST readme.txt for the FAST toolkit (TXT 4K)
The next sections introduce Echo, the MC trace and introspection tool, and describe how to use FAST data communications features.
Echo is a trace and introspection tool that you can run in a separate browser session alongside the Flex application you are developing. You can use Echo in two distinct ways:
Figure 1 shows the Echo Console after a user starts the Echo example application, clicks all three buttons in the application, and uses the Echo Inspector to expand the dummyData object:
Figure 1: The Echo Console after expanding the dummyData object
See the Echo Console live at: flexapps.macromedia.com/fast/fastTutorial/fast/echo/console/EchoConsole.mxml
Run the Echo example program at: flexapps.macromedia.com/fast/fastTutorial/_005_EchoExample.mxml
Figure 2 shows the Echo example program user interface:
Figure 2: The Echo Example Application
The following source code is from the Echo example application (_005_EchoExample.mxml). Take note of the highlighted items:
<mx:Panel title="Echo">
<mx:ControlBar>
<mx:Button label="Info message"
click="Echo.info('This is my info message.');"/>
<mx:Button label="Debug message"
click="Echo.debug('Debug message.');"/>
<mx:Button label="Error message"
click="Echo.error('Error message! TILT!');"/>
</mx:ControlBar>
</mx:Panel>
<mx:Script>
import fast.echo.Echo;
var dummyData:Object;
private function initApp(){
// Initialize Echo
Echo.enableDebug();
Echo.clearConsole();
// Log a message
Echo.debug("Application initialized");
// Initialize dummy data
dummyData = new Object();
dummyData.stringParameter = "This is a string";
dummyData.dateParameter = new Date();
dummyData.objectParameter = {parm1:"hello",
parm2:"Kaiser Sosay",
parm3:12345};
dummyData.arrayParameter = new Array();
dummyData.arrayParameter.push(123);
dummyData.arrayParameter.push(45.6);
dummyData.arrayParameter.push("seven eight nine");
}
</mx:Script>
Notice the following important points in this example:
Find additional information about Echo in the FAST API documentation included with the FAST download in the Requirements section.
The following sections describe the data communications features in FAST. First, you’ll see a simple example of how remote data services are accessed. Next, you’ll read about the many useful features that the FAST provides “for free”, such as client-side data caching; support for RemoteObject, WebService, and HTTPService tags; and error handling. Finally, you’ll read about the classes that implement FAST data communications.
We use a trivial example application to present the essential data communications features of FAST (_010_SimpleDataRetrieval.mxml). Figure 3 shows how the application appears to the user:
Figure 3: The Simple Data Retrieval Example Application
You can run the code at: flexapps.macromedia.com/fast/fastTutorial/_010_SimpleDataRetrieval.mxml.
Flex source for the previous example application follows: (You can follow this code in the _011_SimpleDataRetrieval_minimal.mxml file, available in the Requirements section). Note the highlighted areas.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<s:_01_SimpleProxyFactory xmlns:s="services.*"
debug="true"/>
<mx:DataGrid dataProvider="{customerSummaryArray}"
width="100%" height="100%"/>
<mx:Button label="Get data"
click="getPersonData()"/>
<mx:Script>
<![CDATA[
import fast.services.ProxyFactory;
import fast.services.Proxy;
private var customerSummaryArray:Array;
private function getPersonData(){
var proxy:Proxy = ProxyFactory.getProxy("simpleService");
proxy.invoke("generateCustomerSummaryList", //remote method
this, //local reply object
"customerSummaryArray", //local reply target
//remote method inputs:
50, //- # records requested
1, //- index of first record
0); //- server delay (ms)
}
]]>
</mx:Script>
</mx:Application>
The first highlighted line above refers to the proxy factory below (_01_SimpleProxyFactory.mxml):
<?xml version="1.0" encoding="utf-8"?>
<s:ProxyFactory xmlns:mx="http://www.macromedia.com/2003/mxml"
xmlns:s="fast.services.*">
<mx:RemoteObject id="simpleService"
named="FastReplyGenerator"
result="resultHandler(event)"
fault="faultHandler(event)"
showBusyCursor="true">
</mx:RemoteObject>
</s:ProxyFactory>
The preceding Flex code calls this remote Java method on the samples.fastTutorial.ReplyGenerator class:
public ArrayList generateCustomerSummaryList(int replySize,
int firstIndex,
int serverDelay)
throws InterruptedException {
. . .
}
Notice the following main points in this example:
ProxyFactory subclass is defined declaratively. See the reference to _01_SimpleProxyFactory at the beginning of the Flex code above. Also, see the contents of _01_SimpleProxyFactory.mxml and note that _01_SimpleProxyFactory extends the fast.services.ProxyFactory base class.ProxyFactory.getProxy() matches the id of a service tag in the ProxyFactory subclass. In the example, this id is "simpleService".ProxyFactory.getProxy().ProxyFactory.debug is true.Remote services are accessed through the proxy.invoke() method. Parameters to this function include:
RemoteObject) or operation (for WebService). In the example this value is "generateCustomerSummaryList".this and "customerSummaryArray" in the example. Target can be a property, as in this example, or a function.Figure 4 shows the FAST example program client-side data caching:
Figure 4: The Client-Side Data Caching Example Application
See it live at: flexapps.macromedia.com/fast/fastTutorial/_020_ClientSideDataCache.mxml.
The example program retrieves data from a Java server using a remote method called getCustomerDetail. The getCustomerDetail method waits three seconds before returning, which makes the effect of client-side caching more noticeable. Client-side caching is enabled for calls to the getCustomerDetail method, which causes the proxy.invoke() method to go through the following extra steps on every call:
Caching is enabled in the ProxyFactory class. In the example application, (_020_ClientSideDataCache.mxml) the ProxyFactory is defined in line 10:
<s:_02_ClientDataCacheProxyFactory xmlns:s="services.*" debug="true"/>
The ProxyFactory source (_02_ClientDataCacheProxyFactory.mxml) shows the syntax for enabling the cache:
<?xml version="1.0" encoding="utf-8"?>
<s:ProxyFactory xmlns:mx="http://www.macromedia.com/2003/mxml"
xmlns:s="fast.services.*">
<mx:RemoteObject id="cachedService"
named="FastReplyGenerator"
result="resultHandler(event)"
fault="faultHandler(event)"
showBusyCursor="true">
</mx:RemoteObject>
<s:cachedMethods>
<mx:Array>
<s:CachedMethod serviceName="cachedService"
methodName="getCustomerDetail"/>
</mx:Array>
</s:cachedMethods>
</s:ProxyFactory>
This is the only change needed to enable caching. All other application logic is the same with or without caching enabled . As the example program shows, you can dump the cache with the following syntax:
proxy.dumpCache("getCustomerDetail");
To understand FAST caching more deeply, examine the Echo console output produced by the caching example applications.
FAST supports the three main data communication protocols that Flex 1.5 supports natively: RemoteObject, WebService, and HTTPService. The previous examples demonstrate support of the RemoteObject protocol.
The FAST syntax for the WebService protocol is identical to that used for the RemoteObject protocol. The only difference is in the ProxyFactory, where you use the WebService tag instead of RemoteObject. The web services example program (_030_WebService.mxml) is identical to the previous example, except that it communicates through SOAP/WebService rather than AMF/RemoteObject. Here is the web service example application’s ProxyFactory class (_03_ClientDataCacheProxyFactory_WS.mxml):
<?xml version="1.0" encoding="utf-8"?>
<s:ProxyFactory xmlns:mx="http://www.macromedia.com/2003/mxml"
xmlns:s="fast.services.*">
<mx:WebService id="cachedService_ws"
serviceName="FastReplyGenerator"
result="resultHandler(event)"
fault="faultHandler(event)"
showBusyCursor="true">
</mx:WebService>
<s:cachedMethods>
<mx:Array>
<s:CachedMethod serviceName="cachedService_ws"
methodName="getCustomerDetail"/>
</mx:Array>
</s:cachedMethods>
</s:ProxyFactory>
Run the sample code at: flexapps.macromedia.com/fast/fastTutorial/_030_WebService.mxml.
Conceptually, FAST support for the HTTPService protocol is very similar to that of the RemoteObject and WebService protocols, but the syntax differs in some ways. The following snippets come from the HTTPService example program, _040_HTTPService.mxml. For the HTTPService application, you import a different proxy class:
import fast.services.HttpProxy;
Get an HttpProxy instance through a different ProxyFactory method:
var httpProxy:HttpProxy = ProxyFactory.getHttpProxy("httpService");
The call to invoke a remote HTTP service includes a parameter that specifies which part of the reply XML object should be returned to the caller. See pathInResult in the code snippet below:
httpProxy.requestXmlData(targetUrl, //target url
pathInResult, //path in result to needed data
this, //local reply object
"customerSummaryArray",//local reply target
//service inputs:
{replySize:20, //- # records
firstIndex:2, //- first record index
serverDelay:0}); //- server delay (ms)
Run the sample code at: flexapps.macromedia.com/fast/fastTutorial/_040_HTTPService.mxml.
In the example program, pathInResult is set to “custSummList.custSumm”. The server reply looks like the following:
<custSummList>
<custSumm>
<lastName>Sosay2</lastName>
<firstName>Kaiser2</firstName>
<customerId>ID1002</customerId>
<address>2 Hill St., Mytown MA</address>
<phoneNumber>(321) 456-10002</phoneNumber>
</custSumm>
<custSumm>
<lastName>Sosay3</lastName>
<firstName>Kaiser3</firstName>
<customerId>ID1003</customerId>
<address>3 Hill St., Mytown MA</address>
<phoneNumber>(321) 456-10003</phoneNumber>
</custSumm>
. . .
<custSummList>
After the reply XML is converted to Object form, custSumList.custSumm evaluates to an array of objects that display as follows in the Echo Console:
Figure 5: Echo Inspector Display of HTTPService Result Array
The other important thing to note about HttpProxy.requestXmlData() is that all input parameters are passed to the server through the last (the fifth) parameter. For form/url-encoded data, all inputs are passed in an object, as shown in the previous example. For application/xml encoding, an XML object would be passed instead.
FAST data access eliminates silent failures and provides all available error-related information to the developer in an easily-accessible manner. FAST handles the following error types:
Server-side errors
Infrastructure errors
Client-side errors
The example application shown in Figure 6 forces many types of data access failure.
Figure 6. The Error Handling Example Application
You can try this functionality at: flexapps.macromedia.com/fast/fastTutorial/_050_ErrorHandling.mxml.
The code behind each of the “Go” buttons intentionally causes a system error. For example, the following code sample uses the RemoteObject proxy to call the remote method, getCustomerDetail, with the wrong number of input parameters:
roProxy.invoke("getCustomerDetail",
this,
"customerDetail",
"ID001");
//2); // Missing input parameter
This causes a dialog box to appear with detailed error information (Figure 7).
Figure 7. Example FAST Fault Pop-Up
The intention of the FAST error handling mechanism is to expedite development. It is meant for use in a development environment, not for your application’s ultimate end user, though it can be adapted for this purpose.
FAST makes possible client-side handling of server-side exceptions. FAST also permits attachment of “extra” data to the request that will be available during response or error handling. See the FAST documentation on Proxy.invoke() and on the ProxyBase class. Also see the last entry in the error handling program (exceptionHandledAtClient) for a working example of these functionalities.
Figure 8 shows a class diagram to give you a circumspect view of the classes that implement FCC data communications.
Figure 8. FAST Data Communications Class Diagram
The MyProxyFactory class is the only class that is application-specific. All other classes are part of the FAST library and should not be modified. The application developer puts the required service tags (such as RemoteObject) into MyProxyFactory, as shown in the previous example programs. You do not have to name this class MyProxyFactory.
ProxyFactory is responsible for managing proxy instances. It ensures that only one proxy instance is created for each service. This supports client-side data caching and optimized data access in large-scale applications. Setting ProxyFactory.debug to true causes the debug subclasses (such as DebugProxy) to be instantiated at runtime, which results in the application generating additional Echo information. You should enable debug for development, but disable it in production. See additional comments below.
ProxyBase implements common reply and fault handling methods. Inputs and fault data can be accessed by the application during reply and fault handling respectively through methods on this class. This class also provides common functionality related to caching.
Proxy exposes the core invoke() method and handles details related to RemoteObject and WebService calls.
The HttpProxy class exposes the core requestXmlData() method and handles details related to HTTPService calls.
Cache manages client-side storage and retrieval of data returned by the server.
DebugProxy, DebugHttpProxy, and DebugCache generate Echo data that is useful for diagnostic and performance optimization purposes. These classes also add error handling unnecessary in a production setting, such as invalid remote method. These classes are instantiated at runtime only if ProxyFactory.debug is true. Otherwise, the application uses their higher performance, less verbose base classes.
FaultHandler presents pop-up dialog boxes with error information. The developer can change the default class used for the pop-up message. See the error handling example program for usage tips.
This article is a user guide for the Flex Application Starter Toolkit, a free software toolkit that makes Flex development faster and easier. FAST addresses two important aspects of Flex application development: event logging and data communications. The underlying architecture of FAST supports large-scale and multi-developer Flex projects. Its design and features were determined by extensive hands-on experience of the Macromedia Consulting team.
The first section of this article showed Echo, a Flex-based event logging and introspection tool. Subsequent sections gave more detailed information about the data communication features of the FAST. The final section offered a holistic view of the classes within FAST data communications.
This article did not address how you can apply FAST to large scale and multi-developer projects. This article left out some technical details that any interested developer can find in the documentation or in the example programs listed in the Requirements section.
Please send questions, comments, change requests, bug reports, enhancements, and requests for notification about updates to jbennett@macromedia.com.
Thank you to Mike Montagna for his work on Echo, to Peter Baird for the example application UI designs, to Christophe Coenraets for his invaluable advice and prodding, and to all the other MC team members for being an awesome group to work with.
John Bennett is an architect in the recently formed Macromedia Consulting group. Macromedia Consulting acts as a catalyst for Flex development projects with strategic customers and partners, driving early phase development projects that demonstrate best practices in Rich Internet Application development. Before joining Macromedia, John was an architect and developer creating enterprise software solutions for financial services companies.