12.2 Separation of Functionality

A Flash Remoting application is a client/server application. You should have a clean separation of client and server duties, however. The server-side services should be operable in any situation, whether being accessed by a Flash interface, HTML interface, desktop application, or other web service. For that reason, it is not advisable to use the Flash object on the server. In Example 2-5, you saw the HelloUser service written using C# in an ASP.NET environment:

<%@ Page Language="C#"%>
<%@ Register TagPrefix="MyTag" Namespace="FlashGateway" Assembly="flashgateway" %>
<MyTag:Flash ID="Flash" Runat="Server" />
  if (Flash.Params.Count > 0) {
  String username = Flash.Params[0].ToString( );
  String currentTime = DateTime.Now.ToLongTimeString( );
  Flash.Result = "Hello " + username + ". It is " + currentTime;

I presented it because it is a part of Flash Remoting that you should know about?and it is frequently an easy way to accomplish a task?but it is not always a good way to code your remote service. The Flash object is available and easy to use, but you should carefully consider the consequences of using the Flash object, as it ties the remote service to the Flash application (preventing you from building a non-Flash interface to the service).

There are several other considerations to separating the client and server. Flash Remoting raises a dilemma?where does the functionality belong? Some functionality is plainly client-side functionality, and some is plainly server-side. Some of it might be in-between and could go either way. For example, you can filter large sets of data in the middle tier, where you have a known environment and resources, versus doing it on the client side within Flash, which, depending on the client's machine, might not perform well. In this case, you may want to initially sort the data set on the server, and then have any user-initiated sorts occur within the Flash Player. This is a good trade-off between client-side processing concerns and the extra bandwidth required to transfer data sets to and from the server.

The database should handle as much data processing as possible, because that is its function and it is good at it. Such things as sorting and filtering recordsets, especially large recordsets, should be left to the database whenever possible.

An example of how you might enhance a server-side method to be more versatile and separate from the client is to manually manipulate your resultset before sending it to Flash. To demonstrate what I mean, think of a resultset that feeds a ComboBox. Frequently, you want to add a display item or an option for "All" in a ComboBox. One of the ways to do this is to add the text manually on the client after the resultset is returned. Sometimes, it makes sense to add the logic to the server so that the client merely has to display what is returned, without doing any manipulation. Performing the processing on the server side makes for a faster client experience and, as an added benefit, if you have to create an HTML interface for the same type of ComboBox, you don't have to do any client-side manipulation of code in your HTML page either. Example 12-1 shows the ColdFusion code to manipulate a Query object on the server, which populates a client-side ComboBox.

Example 12-1. Enhancing a recordset to include static items directly in the remote service
<cffunction name="getTypes" access="remote" returntype="query">
<!--- First, get the data from the database
      The cachedwithin attribute keeps the query in memory for
       quicker access--->
  <cfquery name="rsGetContentTypes"
   cachedwithin="#CreateTimeSpan(7, 0, 0, 0)#">
   SELECT type_ID, type_Desc from mytypes
<!--- Next, add a row to the query result and
      set new fields for the static option --->
  <cfset temp = QueryAddRow(rsGetContentTypes)>
  <cfset Temp = QuerySetCell(rsGetContentTypes, "type_id", 0)>
  <cfset Temp = QuerySetCell(rsGetContentTypes, "type_desc", "ALL")>
<!--- Lastly, do a query of a query and return the query to the
      caller ordering on the type_id field --->
  <cfquery name="rsTypesDropdown" dbtype="query">
   SELECT * FROM rsGetContentTypes ORDER BY type_id
  <cfreturn rsTypesDropdown />

In this case, we could have added the row on the Flash client using ActionScript code, but manipulating UI components can slow down an application?especially if you have more than a few in an interface. Example 12-1 shows another aspect of ColdFusion?the ability to cache a resultset. The attribute cachedwithin="#CreateTimeSpan(7, 0, 0, 0)#" creates a seven-day cache; the database is hit only once per week for this query.

This type of functionality can even be included in your database in a stored procedure:

CREATE PROCEDURE spGetCategoriesDropdown
SELECT CategoryID, CategoryName
FROM categories
SELECT 0 as CategoryID, 'All' as CategoryName

The stored procedure returns the resultset with the values already in place for populating the drop-down list.

    Part III: Advanced Flash Remoting