In my previous post, I provided an example of an Apollo application using the Flex Message Service. Since then, a number of people have asked for examples of Apollo applications accessing data using the Flex Data Management services. So here is a simple Contact Management application that demonstrates this integration.
Using the Data Services to work with data in Apollo offers several benefits. First, just like for traditional browser-based Flex apps, the Data Management Services automate the synchronization of data between the client and the middle-tier. In other words, you don’t have to flag/keep track of the changes made at the client-side, and then make corresponding RPC calls to send changes to the server: all that is managed automatically.
For this application, I actually used LiveCycle Data Services (the new name for Flex Data Services) 2.5 currently in beta 2, which offer additional benefits in the context of this application:
- Using the new SQL assembler, you don’t have to write server-side components if you don’t want/need to: you just provide a series of SQL statements indicating how data should be retrieved, and how changes should be persisted in the database. The SQL assembler makes it extremely fast and easy to create applications that don’t require sophisticated persistence logic.
- In 2.5, the DataService API provides methods (such as dataService.saveCache() / dataService.clearCache()) to save data locally and manipulate the local data store. You can also automatically synchronize the changes you made offline with the server. I ran into a bug in LCDS beta 2 that prevented me from implementing offline caching in this sample. The bug is fixed post beta 2 and I will share an updated version of the app when the bits become publicly available.
- Install LiveCycle Data Services 2.5 beta here
- Modify the flexdemosb database file to add the contact table: replace WEB-INF\db\flexdemodb\flexdemodb.script with this version.
- Open WEB-INF\flex\data-management-config.xml and add the following destination.
<destination id="sql-contact"> <adapter ref="java-dao" /> <properties> <use-transactions>true</use-transactions> <source>flex.data.assemblers.SQLAssembler</source> <scope>application</scope> <metadata> <identity property="CONTACT_ID"/> </metadata> <network> <session-timeout>20</session-timeout> <paging enabled="false" pageSize="10" /> <throttle-inbound policy="ERROR" max-frequency="500"/> <throttle-outbound policy="REPLACE" max-frequency="500"/> </network> <server> <database> <driver-class>org.hsqldb.jdbcDriver</driver-class> <!-- Modify the URL below with the actual location of the flexdemodb database on your system --> <url>jdbc:hsqldb:file:C:/lcds/jrun4/servers/default/samples/WEB-INF/db/flexdemodb/flexdemodb</url> <username>sa</username> <password></password> <login-timeout>15</login-timeout> </database> <actionscript-class>Contact</actionscript-class> <fill> <name>all</name> <sql>SELECT * FROM CONTACT</sql> </fill> <get-item> <sql>SELECT * FROM CONTACT WHERE CONTACT_ID = #CONTACT_ID#</sql> </get-item> <create-item> <sql>INSERT INTO CONTACT (FIRST_NAME,LAST_NAME,EMAIL,PHONE,ADDRESS,CITY,STATE,ZIP,COUNTRY,NOTES) VALUES (#FIRST_NAME#, #LAST_NAME#, #EMAIL#, #PHONE#, #ADDRESS#, #CITY#, #STATE#, #ZIP#, #COUNTRY#, #NOTES#)</sql> <id-query>CALL IDENTITY()</id-query> <!-- HSQLDB syntax to retrieve value of autoincremented column --> </create-item> <update-item> <sql>UPDATE CONTACT SET FIRST_NAME=#FIRST_NAME#,LAST_NAME=#LAST_NAME#,EMAIL=#EMAIL#,PHONE=#PHONE#,ADDRESS=#ADDRESS#,CITY=#CITY#,STATE=#STATE#,ZIP=#ZIP#,COUNTRY=#COUNTRY#,NOTES=#NOTES# WHERE CONTACT_ID=#_PREV.CONTACT_ID#</sql> </update-item> <delete-item> <sql>DELETE FROM CONTACT WHERE CONTACT_ID=#CONTACT_ID#</sql> </delete-item> <count> <name>all</name> <sql>SELECT count(*) FROM CONTACT</sql> </count> </server> </properties> </destination>
- Start the server
- Install contacts.air and run the application
NOTE: The application has been compiled assuming that an RTMP endpoint named my-rtmp is configured at rtmp://localhost:2037. If your server isn’t configured that way, you will have to recompile the application. You can also provide the endpoints at runtime. See my previous post for more information on defining a ChannelSet.
You can download the source code here.